Blookeynose
Blookeynose

Reputation: 13

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:

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

Upvotes: 1

Views: 1049

Answers (1)

H.A.H.
H.A.H.

Reputation: 3917

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.

Upvotes: 0

Related Questions