XAML 无法绑定ContentView控件的属性

wf82jlnq  于 2023-01-03  发布在  其他
关注(0)|答案(1)|浏览(170)

我有一个名为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?

pdsfdshx

pdsfdshx1#

ContentView具有可以覆盖的OnBindingContextChanged方法

相关问题