我如何在.NET MAUI中绑定窗口宽度以进行布局更改?

huangapple go评论72阅读模式
英文:

How can I bind the window width for layout changes in .NET MAUI?

问题

以下是您要翻译的部分:

"Bind to the Window width for Layout changing based on window size.

I'm using the concept of This github repository based for WPF but I have been trying to adapt it for MAUI. This is also where I acquired the "IsGreaterThanConverter" and "IsLessThanConverter." The implementation of "TemplatedContentPresenter" was found Here.

I understand there is "DataTemplateSelector" but I have not worked with them and would not know how to implement it in this scenario.

I get this error:

No property, BindableProperty, or event found for "AncestorType", or mismatching type between value and property.

MainWindow.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Local.MainPage"
             xmlns:viewModels="clr-namespace:Local.ViewModels"
             xmlns:local="clr-namespace:Library;assembly=Library">
    
    <ContentPage.BindingContext>
        <viewModels:MainWindowViewModel/>
    </ContentPage.BindingContext>

    <ContentPage.Resources>
    </ContentPage.Resources>

    <local:TemplatedContentPresenter x:Name="Main" Data="{Binding}">
        <local:TemplatedContentPresenter.Style>
            <Style TargetType="local:TemplatedContentPresenter">

                <!--// Default Layout //-->

                <Setter Property="DataTemplate"
                            Value="{StaticResource Desktop_Layout}" />

                <Style.Triggers>

                    <!--// Desktop Layout // {width > 1400px}-->

                    <DataTrigger TargetType="local:TemplatedContentPresenter" Binding="{Binding Path=Width, Source={RelativeSource AncestorType=ContentPage}, Converter={x:Static local:IsGreaterThanConverter.Instance}, ConverterParameter=1400}"
                                     Value="True">

                        <Setter Property="DataTemplate"
                                    Value="{StaticResource Desktop_Layout}" />

                    </DataTrigger>

                    <!--// Tablet Landscape Layout // {width < 1200px}-->

                    <DataTrigger TargetType="local:TemplatedContentPresenter" Binding="{Binding Path=Width, Source={RelativeSource AncestorType=ContentPage}, Converter={x:Static local:IsLessThanConverter.Instance}, ConverterParameter=1200}"
                                     Value="True">

                        <Setter Property="DataTemplate"
                                    Value="{StaticResource Tablet_Layout}" />

                    </DataTrigger>

                    <!--// Mobile Landscape Layout // {width < 812px}-->

                    <DataTrigger TargetType="local:TemplatedContentPresenter" Binding="{Binding Path=Width, Source={RelativeSource AncestorType=ContentPage}, Converter={x:Static local:IsLessThanConverter.Instance}, ConverterParameter=812}"
                                     Value="True">

                        <Setter Property="DataTemplate"
                                    Value="{StaticResource Mobile_Layout}" />

                    </DataTrigger>

                </Style.Triggers>

            </Style>
        </local:TemplatedContentPresenter.Style>
    </local:TemplatedContentPresenter>

</ContentPage>

Edit:
For anyone who might be trying to accomplish a similar binding, I realized I did not set the RealativeSource "Mode" to "FindAncestor."

My DataTrigger line should read as follows:

英文:

Bind to the Window width for Layout changing based on window size.

I'm using the concept of This github repository based for WPF but I have been trying to adapt it for MAUI. This is also where I acquired the "IsGreaterThanConverter" and "IsLessThanConverter." The implementation of "TemplatedContentPresenter" was found Here.

I understand there is "DataTemplateSelector" but I have not worked with them and would not know how to implement it in this scenario.

I get this error:
> No property, BindableProperty, or event found for "AncestorType", or mismatching type between value and property.

MainWindow.xaml:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;ContentPage xmlns=&quot;http://schemas.microsoft.com/dotnet/2021/maui&quot;
xmlns:x=&quot;http://schemas.microsoft.com/winfx/2009/xaml&quot;
x:Class=&quot;Local.MainPage&quot;
xmlns:viewModels=&quot;clr-namespace:Local.ViewModels&quot;
xmlns:local=&quot;clr-namespace:Library;assembly=Library&quot;&gt;
&lt;ContentPage.BindingContext&gt;
&lt;viewModels:MainWindowViewModel/&gt;
&lt;/ContentPage.BindingContext&gt;
&lt;ContentPage.Resources&gt;
&lt;/ContentPage.Resources&gt;
&lt;local:TemplatedContentPresenter x:Name=&quot;Main&quot; Data=&quot;{Binding}&quot;&gt;
&lt;local:TemplatedContentPresenter.Style&gt;
&lt;Style TargetType=&quot;local:TemplatedContentPresenter&quot;&gt;
&lt;!--// Default Layout //--&gt;
&lt;Setter Property=&quot;DataTemplate&quot;
Value=&quot;{StaticResource Desktop_Layout}&quot; /&gt;
&lt;Style.Triggers&gt;
&lt;!--// Desktop Layout // {width &gt; 1400px}--&gt;
&lt;DataTrigger TargetType=&quot;local:TemplatedContentPresenter&quot; Binding=&quot;{Binding Path=Width, Source={RelativeSource AncestorType=ContentPage}, Converter={x:Static local:IsGreaterThanConverter.Instance}, ConverterParameter=1400}&quot;
Value=&quot;True&quot;&gt;
&lt;Setter Property=&quot;DataTemplate&quot;
Value=&quot;{StaticResource Desktop_Layout}&quot; /&gt;
&lt;/DataTrigger&gt;
&lt;!--// Tablet Landscape Layout // {width &lt; 1200px}--&gt;
&lt;DataTrigger TargetType=&quot;local:TemplatedContentPresenter&quot; Binding=&quot;{Binding Path=Width, Source={RelativeSource AncestorType=ContentPage}, Converter={x:Static local:IsLessThanConverter.Instance}, ConverterParameter=1200}&quot;
Value=&quot;True&quot;&gt;
&lt;Setter Property=&quot;DataTemplate&quot;
Value=&quot;{StaticResource Tablet_Layout}&quot; /&gt;
&lt;/DataTrigger&gt;
&lt;!--// Mobile Landscape Layout // {width &lt; 812px}--&gt;
&lt;DataTrigger TargetType=&quot;local:TemplatedContentPresenter&quot; Binding=&quot;{Binding Path=Width, Source={RelativeSource AncestorType=ContentPage}, Converter={x:Static local:IsLessThanConverter.Instance}, ConverterParameter=812}&quot;
Value=&quot;True&quot;&gt;
&lt;Setter Property=&quot;DataTemplate&quot;
Value=&quot;{StaticResource Mobile_Layout}&quot; /&gt;
&lt;/DataTrigger&gt;
&lt;/Style.Triggers&gt;
&lt;/Style&gt;
&lt;/local:TemplatedContentPresenter.Style&gt;
&lt;/local:TemplatedContentPresenter&gt;
&lt;/ContentPage&gt;

Edit:
For anyone who might be trying to accomplish a similar binding, I realized I did not set the RealativeSource "Mode" to "FindAncestor."

My DataTrigger line should read as follows:

&lt;DataTrigger TargetType=&quot;local:TemplatedContentPresenter&quot; Binding=&quot;{Binding Path=Width, Source={RelativeSource Mode=FindAncestor, AncestorType={x:Type ContentPage}}, Converter={x:Static local:IsGreaterThanConverter.Instance}, ConverterParameter=1400}&quot; Value=&quot;True&quot;&gt;

答案1

得分: 0

为什么不使用不同的页面?

MVVM和绑定的好处是您的代码(ViewModels)不知道是谁呈现数据(Views)。

你唯一需要修改的是你的导航服务,以考虑你使用的操作系统,并相应地转到Win/Android页面。

现在,如果您希望在手动调整窗口大小时看到更改,这就是另一回事。

但这样做可以保持视图分离。

英文:

Why don't you use different pages?

The benefits of MVVM and bindings is that your code (ViewModels) do not have any clue about who presents the data.(Views).

The only thing you need to modify, is your navigation service to take into account what OS are you using, and go to Win/Android pages accordingly.

Now, if you expect to see changes when you manually resize the window, this is different story.

But this what I do keeps the views separate.

huangapple
  • 本文由 发表于 2023年5月21日 07:32:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76297731.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定