我有一个名为HomePageOrientationViewLoader的内容视图,我想在名为HomePage的内容页面中使用它。如果方向为横向,HomePageOrientationViewLoader将加载名为HomePageLandscape的内容视图;如果方向为纵向,则加载名为HomePagePortrait的内容视图。
我这样做是为了我可以加载一个不同的布局为横向vs纵向,这样我就可以优化我的布局。
我的问题是我使用依赖项注入来注入我的ViewModel HomeViewModel。我将其注入到ContentPage主页中,并尝试将HomeViewModel从ContentPage主页的XAML传递到HomePageOrientationViewLoader的标记中。
下面是我的内容页面的HomePage.xaml.cs代码:
using ScoreKeepersBoard.ViewModels;
namespace ScoreKeepersBoard.Views;
public partial class HomePage : ContentPage
{
public HomePage(HomeViewModel homeViewModelInj)
{
HomeViewModel = homeViewModelInj;
BindingContext = homeViewModelInj;
InitializeComponent();
}
HomeViewModel HomeViewModel { get; set; }
protected override void OnNavigatedTo(NavigatedToEventArgs args)
{
((HomeViewModel)BindingContext).CreateInitialGameTypes();
base.OnNavigatedTo(args);
}
}
下面是我的内容页的HomePage.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>
<controls:HomePageOrientationViewLoader
BindingContext="{Binding HomeViewModel}"
>
</controls:HomePageOrientationViewLoader>
</VerticalStackLayout>
</ContentPage>
下面是我的内容视图的HomePageOrientationViewLoader.xaml.cs代码:
using System.Reflection;
using ScoreKeepersBoard.ViewModels;
namespace ScoreKeepersBoard.ContentViews;
public partial class HomePageOrientationViewLoader : ContentView
{
public ContentView homePagePortraitContentView;
public ContentView homePageLandscapeContentView;
public HomeViewModel HomeViewModel { get; set; }
public HomePageOrientationViewLoader()
{
InitializeComponent();
try
{
//homeVM is always null
HomeViewModel homeVM = ((HomeViewModel)BindingContext);
string entryValue = homeVM.EntryValue;
homePagePortraitContentView = new HomePagePortrait(homeVM);
homePageLandscapeContentView = new HomePageLandscape(homeVM);
}
catch (Exception e)
{
string message = e.Message;
}
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)
{
this.Content = homePageLandscapeContentView;
}
else if (e.DisplayInfo.Orientation == DisplayOrientation.Portrait)
{
this.Content = homePagePortraitContentView;
}
else
{
this.Content = homePagePortraitContentView;
}
}
}
代码编译并运行,但问题是HomePageOrientationViewLoader上的BindingContext始终为null。我希望这是从HomePage ContentPage中ContentView的标记中定义的属性设置的。
我还尝试将HomePage ContentPage中ContentView标记中的HomePageOrientationViewLoader标记设置为HomePageOrientationViewLoader上定义的普通属性,如下所示:
<?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>
<controls:HomePageOrientationViewLoader
HomeViewModel = "{Binding HomeViewModel}">
</controls:HomePageOrientationViewLoader>
</VerticalStackLayout>
</ContentPage>
但是这个代码甚至不能编译,我得到了以下错误:
/用户/远程命令/项目/记分板/视图/主页.xaml(13,13):错误XFC 0009:找不到“HomeViewModel”的属性、BindableProperty或事件,或者值和属性之间的类型不匹配。(XFC 0009)
这显然不是真的,因为HomeViewModel是HomePage内容页面和HomePageOrientationViewLoader内容视图上的属性。
我需要能够在HomePageOrientationViewLoader中有HomeViewModel,然后将其传递给HomePageLandscape和HomePagePortrait ContentViews,这样当用户在纵向和横向视图之间切换时,它们就可以共享相同的ViewModel,但到目前为止,我还不能让这个工作。我将非常感谢任何帮助。
- 更新 * Jason评论:“如果您希望控件具有与页面相同的BindingContext,则不需要执行任何操作-它应该自动继承。”我只是尝试删除控件标记上的绑定属性,如下所示:
<?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>
<controls:HomePageOrientationViewLoader>
</controls:HomePageOrientationViewLoader>
</VerticalStackLayout>
</ContentPage>
当我的HomePageOrientationViewLoader页面加载构造函数时,HomePageOrientationViewLoader的BindingContext中的HomeViewModel仍然为空:
UPDATE 2 Jason说你不应该假设BindingContext是在构造函数中设置的,他是对的,当我的HomePageOrientationViewLoader第一次加载ContentView时,ContentView是没有设置的,但是当我改变方向并查看BindingContext是什么时,情况是这样的:
private void Current_MainDisplayInfoChanged(object sender, DisplayInfoChangedEventArgs e)
{
HomeViewModel homeVM = ((HomeViewModel)BindingContext);
homePageLandscapeContentView.BindingContext = homeVM;
homePagePortraitContentView.BindingContext = homeVM;
...
}
从HomePageOrientationViewLoader的BindingContext设置的homeVM不再为空。然后我可以设置HomePageLandscape和HomePagePortrait的BindingContext,它们的ViewModel是活动的和绑定的。对我来说唯一的问题是,当页面最初加载时,HomePageLandscape和HomePagePortrait没有设置它们的BindingContext。
如何解决这个问题?ContentView上是否有某个事件在设置BindingContext时被触发,以便我可以覆盖该事件并将HomePageLandscape和HomePagePortrait的绑定上下文绑定到HomePageOrientationViewLoader的BindingContext?
1条答案
按热度按时间pdsfdshx1#
ContentView
具有可以覆盖的OnBindingContextChanged
方法