[英]In .NET MAUI is there a way to choose a different XAML view based upon whether the device is in Landscape or Portrait
我正在使用 .NET MAUI,我有一个相当复杂的特定视图,如果设备方向是纵向,我宁愿有不同的布局,如果设备方向是横向。
很久以前,我修改了 Android 编程,对于 Android Studio,有一种方法可以在设备横向时选择 XAML 文件,而在设备纵向时选择不同的 XAML 文件。
这对 MAUI 来说可能吗? 如果不是,这方面的最佳做法是什么?
这是我的布局,在横向模式下,我可以在一行中放置 3 个主要部分,但这在纵向模式下不起作用,而在纵向模式下,我希望中间的主要元素位于下一行。
以下是我在 Photoshop 上创建的肖像与风景模型的示例:
更新解决方案*************** 我正在尝试 FreakyAli 发布的解决方案并且有一个主要工作的原型,所以任何想要根据屏幕方向使用不同的 XAML 布局的人可以使用这种方法。
我在我的解决方案中创建了一个名为“ContentViews”的新文件夹。 我添加了 3 个新的 ContentViews(带有后面代码的 XAML):
HomePageOrientationViewLoader 稍后将直接加载到 HomePage.xaml 文件中。 这是将在纵向模式下加载 HomePagePortrait ContentView 或在横向模式下加载 HomePageLandscape ContentView 的控件。
namespace ScoreKeepersBoard.ContentViews;
public partial class HomePageOrientationViewLoader : ContentView
{
public ContentView homePagePortraitContentView;
public ContentView homePageLandscapeContentView;
public HomePageOrientationViewLoader()
{
InitializeComponent();
homePagePortraitContentView = new HomePagePortrait();
homePageLandscapeContentView = new HomePageLandscape();
this.Content = homePageLandscapeContentView;
DeviceDisplay.Current.MainDisplayInfoChanged += Current_MainDisplayInfoChanged;
this.Content = DeviceDisplay.Current.MainDisplayInfo.Orientation == DisplayOrientation.Portrait ? homePagePortraitContentView : homePageLandscapeContentView;
}
private void Current_MainDisplayInfoChanged(object sender, DisplayInfoChangedEventArgs e)
{
if (e.DisplayInfo.Orientation == DisplayOrientation.Landscape)
{
// if (this.Content.GetType() is not typeof(HomePageLandscape))
// {
this.Content = homePageLandscapeContentView;
// }
}
else if (e.DisplayInfo.Orientation == DisplayOrientation.Portrait)
{
// if (this.Content.GetType() is not typeof(HomePagePortrait))
// {
this.Content = homePagePortraitContentView;
// }
}
else
{
//Whatever you would like to do if the orientation is unknown.
}
}
}
HomePageOrientationViewLoader.xaml 文件:
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ScoreKeepersBoard.ContentViews.HomePageOrientationViewLoader">
<VerticalStackLayout>
<Label
Text="Welcome to .NET MAUI!"
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentView>
这是 HomePagePortrait.xaml.cs 文件:
namespace ScoreKeepersBoard.ContentViews;
public partial class HomePagePortrait : ContentView
{
public HomePagePortrait()
{
InitializeComponent();
}
}
这是 HomePagePortrait.xaml 文件:
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ScoreKeepersBoard.ContentViews.HomePagePortrait">
<VerticalStackLayout>
<Label
Text="Welcome to .NET MAUI portrait"
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentView>
这是 HomePageLandscape.xaml.cs 文件:
namespace ScoreKeepersBoard.ContentViews;
public partial class HomePageLandscape : ContentView
{
public HomePageLandscape()
{
InitializeComponent();
}
}
这是 HomePageLandscape.xaml 文件:
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ScoreKeepersBoard.ContentViews.HomePageLandscape">
<VerticalStackLayout>
<Label
Text="Welcome to .NET MAUI landscape"
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentView>
我的项目有一个名为 HomePage 的初始主页内容页面。 我们正在将 HomePageOrientationViewLoader ContentView 作为自定义控件加载到 HomePage Content Page 的 xaml 中。 请注意,我必须定义 ContentView 所在的命名空间,并在 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"
xmlns:controls="clr-namespace:ScoreKeepersBoard.ContentViews"
x:Class="ScoreKeepersBoard.Views.HomePage"
Title="HomePage">
<VerticalStackLayout>
<Label
Text="Welcome to .NET MAUI Home Page Content Page"
VerticalOptions="Center"
HorizontalOptions="Center" />
<controls:HomePageOrientationViewLoader></controls:HomePageOrientationViewLoader>
</VerticalStackLayout>
</ContentPage>
这是主页背后的代码
namespace ScoreKeepersBoard.Views;
public partial class HomePage : ContentPage
{
public HomePage(HomeViewModel homeViewModel)
{
InitializeComponent();
}
}
当项目以纵向模式在我的 iphone 模拟器上运行时:
您将看到显示的第二个 label 显示“欢迎使用 .NET MAUI 肖像”,这是肖像内容视图的视图,当我切换到风景时:
您将看到显示的第二个 label 显示“欢迎使用 .NET MAUI 横向”,这是横向内容视图中的视图。
问题
这适用于我的 iPhone 模拟器,但是当我切换到我的 Android 像素 5 模拟器并切换我的切换手机方向时,它不起作用并且插入换行符,不会触发 HomePageOrientationViewLoader 中定义的代码。 新注意事项:我在 Android 实体手机上试过这个,它正在工作,所以它一定是模拟器。
我需要将它用于一个非平凡的示例,该示例的视图 model 将保存体育比赛得分、计时等数据。我想我只需要将视图 model 的 singleton 注入每个视图,它们将只是分享,如果方向切换,其他内容视图将加载,视图 model 将绑定到适当的控件?
FreakyAli 最初建议的代码有这个检查:
if (e.DisplayInfo.Orientation == DisplayOrientation.Landscape) { if (this.Content.GetType() is not typeof(HomePageLandscape)) { this.Content = homePageLandscapeContentView; } }
但是“typeof(HomePageLandscape)”部分给我一个错误,并说需要一个常数。
除此之外,不同方向的不同视图正在工作,我非常感谢 FreakyAli,我相信我会弄清楚为什么 Android 模拟器没有触发方向切换代码。 但建议会很棒。
理想情况下,这就是我处理这种情况的方式:
在我的构造函数中,我会得到 DisplayInfoChanged 事件,如果此信息发生变化,它会通知我,我还会根据当前方向分配我当前的 ContentView:
DeviceDisplay.Current.MainDisplayInfoChanged += Current_MainDisplayInfoChanged;
this.Content = DeviceDisplay.Current.MainDisplayInfo.Orientation == DisplayOrientation.Portrait ? potraitView : landscapeView;
这里的 PortraitView 是一个 ContentView,它是当我的设备处于纵向和反之亦然时我将显示的视图。
然后按如下方式处理方向的运行时变化:
private void Current_MainDisplayInfoChanged(object sender, DisplayInfoChangedEventArgs e)
{
if(e.DisplayInfo.Orientation==DisplayOrientation.Landscape)
{
if(this.Content.GetType() is not typeof(LandscapeView))
{
this.Content = landscapeView;
}
}
else if (e.DisplayInfo.Orientation == DisplayOrientation.Portrait)
{
if (this.Content.GetType() is not typeof(PortraitView))
{
this.Content = portraitView;
}
}
else
{
//Whatever you would like to do if the orientation is unknown.
}
}
希望这对你有帮助!
执行此操作的正确方法是通过 ContentViews,其中您有 2 个 ContentView,一个用于纵向,一个用于横向。 您有另一个 ContentView,用于根据方向选择横向或纵向加载。 我创建了一个教程,将所有部分放在一起: https://codeshadowhand.com.net-maui-different-layouts-for-portrait-vs-landscape/ 非常感谢 FreakyAli 为我指明了正确的方向!! !
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.