英文:
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
你可以在你的视图模型上定义两个属性,并将它们绑定到你的布局的 HeightRequest
和 WidthRequest
属性上。
你可以参考以下的代码:
- 创建一个视图模型并实现
INotifyPropertyChanged
接口,然后添加两个属性Height
和Width
。
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;
}
- 使用示例:
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 => _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;
}
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 > height) ? "Landscape" : "Portrait";
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>
Note:
For more information, you can check document: Device Orientation.
Although this document is about Xamarin.Forms, it also applies to MAUI.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论