1

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">

1 Answers1

0

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.

H.A.H.
  • 2,104
  • 1
  • 8
  • 21
  • I was initially trying to update it as the window resizes, and unless there is a better way than how I was trying to accomplish it, I think you are right and separate views will be the way to go. I got it working but it was glitchy. – Blookeynose May 22 '23 at 01:53
  • @Blookeynose Well you can check this. https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/layouts/device-orientation?tabs=windows. Maui page is not better. And if you check answers like this: https://stackoverflow.com/a/60002457/6643940 (Accepted +4 upvotes), they contain all kind of extremely bad design choices. Something like case TV: button.HeightRequest = 40. Hell no. – H.A.H. May 22 '23 at 09:15