StackLayout的HeightRequest/WidthRequest根据方向而定

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

StackLayout HeightRequest/WidthRequest based on orientation

问题

在.NET MAUI应用中,我使用了CommunityToolkit中的弹出窗口,其中包含一个网格或其他布局。

在外部网格下方的这个布局(在代码中)应该根据屏幕的方向获得HeightRequest和WidthRequest,以便内容始终以良好的可见性呈现,并且按钮等元素可以被点击。在内部网格上,我还想使用其他控件以后选择值。

我可以设置HeightRequest="500"和WidthRequest="300",在竖屏视图下效果很好,但在横屏视图下看起来不好。

有没有一种好的方法,可以根据方向设置这些请求,并在视图更改时进行调整?

英文:

In a .NET MAUI App I use a CommunityToolkit Popup with a Grid or any other Layout inside.

This Layout (in code below the outer Grid) should get a HightRequest and WidthRequest based on the Orientation of the Screen so that the Content is always visible nicely and the Buttons for instance can be clicked. On the inner Grid, I also want to use other controls to select values from later on.

I could set a HeightRequest="500" and WidthRequest="300" which works well when in Portrait View, but doesn't look good when in Landscape View.

Is there a good way, I can set these Requests based on the Orientation and adapt when the View has changed?

<?xml version="1.0" encoding="utf-8" ?>
<toolkit:Popup xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
           xmlns:toolkit="clr-namespace:CommunityToolkit.Maui.Views;assembly=CommunityToolkit.Maui"
           xmlns:ios="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;assembly=Microsoft.Maui.Controls"
           xmlns:loc="clr-namespace:LocalizationResourceManager.Maui;assembly=LocalizationResourceManager.Maui"
           xmlns:viewModels="clr-namespace:OptimizationApp.ViewModels"
           xmlns:databaseModels="clr-namespace:OptimizationApp.DatabaseModels"
           x:DataType="viewModels:CustomPopupViewModel"
           x:Class="MacroOptimizerApp.Pages.Views.Controls.CustomPicker.CustomPopupContentPage"
           CanBeDismissedByTappingOutsideOfPopup="False">
		   
		   
		   
    <Grid RowDefinitions="Auto, Auto, Auto" Background="White">

        <SearchBar Grid.Row="0" ios:SearchBar.SearchBarStyle="Minimal" Text="{Binding SearchText}" Placeholder="{loc:Translate CustomPickerPopup_SearchPlaceholder}" Margin="0, 0, 0, 5"  />

        
        
        <!-- Cancel/OK-Button -->
        <Grid Grid.Row="2" RowDefinitions="35" ColumnDefinitions="Auto, Auto" ColumnSpacing="5" HorizontalOptions="End">

            <Grid.Resources>
                <Style TargetType="Button">
                    <Setter Property="FontAutoScalingEnabled" Value="True" />
                    <Setter Property="HeightRequest" Value="35" />
                    <Setter Property="WidthRequest" Value="100" />
                    <Setter Property="Padding" Value="15, 7, 15, 10" />
                </Style>
            </Grid.Resources>

            <Button Grid.Column="0" Text="{loc:Translate CancelButtonText}" Clicked="CancelButton_Clicked" />
            <Button Grid.Column="1" Text="{loc:Translate OKButtonText}" Clicked="OkButton_Clicked" Command="{Binding OkButtonCommand}" CommandParameter="{Binding SelectedValue}" />

        </Grid>
        
    </Grid>
		   
		   
</toolkit:Popup>

答案1

得分: 0

你可以在你的视图模型上定义两个属性,并将它们绑定到你的布局的 HeightRequestWidthRequest 属性上。

你可以参考以下的代码:

  1. 创建一个视图模型并实现 INotifyPropertyChanged 接口,然后添加两个属性 HeightWidth
public class TestViewModel: INotifyPropertyChanged 
{

    Double _height;
    public Double Height
    {
        get => _height;
        set => SetProperty(ref _height, value);
    }

    Double _width;
    public Double Width
    {
        get => _width;
        set => SetProperty(ref _width, value);
    }

    public TestViewModel()
    {
        Width = 200;
        Height = 200;
    }

    bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Object.Equals(storage, value))
            return false;

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}
  1. 使用示例:

MainPage.xaml.cs

在你的页面上,尝试覆盖 OnSizeAllocated 方法,我们可以检测屏幕的方向,然后根据结果更改视图模型上定义的属性的值。

public partial class MainPage : ContentPage 
{
    TestViewModel viewModel; 

    public MainPage()
    {
        InitializeComponent();

        viewModel = new TestViewModel();    
        this.BindingContext = viewModel;
    }

    private double width = 0;
    private double height = 0;

    protected override void OnSizeAllocated(double width, double height)
    {
        base.OnSizeAllocated(width, height);

        if (width != this.width || height != this.height)
        {
            this.width = width;
            this.height = height;

            if (width > height) // Landscape
            {
                viewModel.Width = 100;
                viewModel.Height = 100;
            }
            else // Portrait
            {
                viewModel.Width = 200;
                viewModel.Height = 200;
            }
        }
    }
}

MainPage.xaml

<Grid  BackgroundColor="Yellow" RowDefinitions="Auto, Auto, Auto"   HeightRequest="{Binding Height}" WidthRequest="{Binding Width}"  > 
            
</Grid>

注意:

更多信息,请查阅文档:Device Orientation

尽管这个文档是关于 Xamarin.Forms 的,但也适用于 MAUI。

英文:

You can define two properties on your view model and bind them to the properties HeightRequest and WidthRequest of your layout.

You can refer to the following code:

1.create a view model and implement interface INotifyPropertyChanged , then add two properties Height and Width.

public class TestViewModel: INotifyPropertyChanged 
{

    Double _height;
    public Double Height
    {
        get =&gt; _height;
        set =&gt; SetProperty(ref _height, value);
    }

    Double _width;
    public Double Width
    {
        get =&gt; _width;
        set =&gt; SetProperty(ref _width, value);
    }

    public TestViewModel()
    {
        Width = 200;
        Height = 200;
    }

    bool SetProperty&lt;T&gt;(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Object.Equals(storage, value))
            return false;

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

2.Usage example:

MainPage.xaml.cs

On your page, try to override method OnSizeAllocated, we can detect the orientation of the screen, then based on the result, we can change the value of the property that defined on the viewmodel.

 public partial class MainPage : ContentPage 
{
    TestViewModel viewModel; 

    public MainPage()
      {
            InitializeComponent();

        viewModel = new TestViewModel();    
        this.BindingContext = viewModel;
      }

    private double width = 0;
    private double height = 0;

    protected override void OnSizeAllocated(double width, double height)
    {
        base.OnSizeAllocated(width, height);
        //var state = (width &gt; height) ? &quot;Landscape&quot; : &quot;Portrait&quot;;

        if (width != this.width || height != this.height)
        {
            this.width = width;
            this.height = height;
            if (width &gt; height)//Landscape
            {
                viewModel.Width = 100;
                viewModel.Height = 100;
            }
            else  //Portrait
            {
                viewModel.Width = 200;
                viewModel.Height = 200;

            }
        }

MainPage.xaml

  &lt;Grid  BackgroundColor=&quot;Yellow&quot; RowDefinitions=&quot;Auto, Auto, Auto&quot;   HeightRequest=&quot;{Binding Height}&quot; WidthRequest=&quot;{Binding Width}&quot;  &gt; 
       
 &lt;/Grid&gt;

Note:

For more information, you can check document: Device Orientation.

Although this document is about Xamarin.Forms, it also applies to MAUI.

huangapple
  • 本文由 发表于 2023年7月17日 13:52:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76701793.html
匿名

发表评论

匿名网友

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

确定