使用XAML在Xamarin.Forms中进行MasterDetailPage的数据绑定

9
到目前为止,大多数使用Xamarin.Forms的示例都是使用C#构建UI。我更喜欢使用XAML来构建UI,并将其绑定到ViewModels。
我在使用Xamarin.Forms.MasterDetailPage与XAML结合使用时遇到了问题,我似乎无法将C#示例移植到XAML + ViewModels。
这是我目前拥有的XAML:
<?xml version="1.0" encoding="UTF-8" ?> 
<MasterDetailPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:NSContacten;assembly=NSContacten"
    x:Class="MasterDetailExample.Main"
    Title="Master Detail Example">

    <MasterDetailPage.Master BindingContext="{Binding Menu}">
        <ContentPage Padding="5, 25">               
            <StackLayout Orientation="Vertical">
                <Label Text="Master" HorizontalOptions="Center" />
                <Label Text="{Binding Subtitle}" HorizontalOptions="Center" />
            </StackLayout>    
        </ContentPage>
    </MasterDetailPage.Master>

    <MasterDetailPage.Detail BindingContext="{Binding Detailpage}">
        <ContentPage Padding="5, 25">    
            <StackLayout Orientation="Vertical">
                <Label Text="Detail" HorizontalOptions="Center" />
                <Label Text="{Binding Subtitle}" HorizontalOptions="Center" />
            </StackLayout>    
        </ContentPage>
    </MasterDetailPage.Detail>    
</MasterDetailPage>

该组件可以正常工作:我确实看到了“Master”和“Detail”标签。但是,绑定的标签(在BindingContext对象上)未显示。
我尝试了很多不同的组合,但仍然无法解决问题:这是如何工作的?我的绑定是否有误(应该在“ContentPage”上进行),我是否不能绑定到.Master和.Detail属性等?“Menu”和“Detailpage”的绑定应该是什么样子的?
如果有人能帮助我,那将是巨大的帮助!下一步将是当在.Master中按下按钮时更改.Detail。提前感谢您的帮助!

谢谢你提出这个问题!我花了一天的时间才弄明白,如果没有这个问题,我可能就不会知道了。 - Tomas Pajonk
1个回答

16

你的 Xaml 已经差不多了,但需要注意以下几点:

  • {BindingContext} 应该写在 ContentPage 标签上而非其他属性上。
  • MasterDetailPage.Master 必须设置 Page.Title 属性,否则会抛出异常。

以下是我测试通过的正确 Xaml 代码:

<?xml version="1.0" encoding="UTF-8" ?> 
<MasterDetailPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:NSContacten;assembly=NSContacten"
    x:Class="MasterDetailExample.Main"
    Title="Master Detail Example">

    <MasterDetailPage.Master>
      <ContentPage Padding="5, 25"  BindingContext="{Binding Menu}" Title="Master">
          <StackLayout Orientation="Vertical">
              <Label Text="Master" HorizontalOptions="Center" />
              <Label Text="{Binding Subtitle}" HorizontalOptions="Center" />
          </StackLayout>
        </ContentPage>

    </MasterDetailPage.Master>

    <MasterDetailPage.Detail>
        <ContentPage Padding="5, 25"  BindingContext="{Binding Detailpage}">

          <StackLayout Orientation="Vertical">
              <Label Text="Detail" HorizontalOptions="Center" />
              <Label Text="{Binding Subtitle}" HorizontalOptions="Center" />
          </StackLayout>

        </ContentPage>
    </MasterDetailPage.Detail>
</MasterDetailPage>

我使用匿名类型作为页面视图模型进行了测试:

public MyMDPage ()
{
    InitializeComponent ();
    BindingContext = new {
        Menu = new { Subtitle = "I'm Master" },
        Detailpage = new { Subtitle = "I'm Detail" }
    };
}

这个代码可以正常工作。在您的情况下,您可能希望使用具体类型而不是匿名类型作为您的视图模型,但您可以理解这个想法。


谢谢Stephane,这个方法非常有效!在.Master上的Page.Title可以被删除(至少对于iOS是这样,我还没有检查其他平台),但MasterDetailPage上的“BindingContext”是我的解决方案的关键。再次感谢! - MarcoK
2
@MarcoK:如果标题不是必填项,那么你没有运行最新版本。请进行NuGet更新。 - Stephane Delcroix
非常感谢您的回答。虽然我在Xamarin.Forms中使用了可绑定属性,但逻辑是相同的。 - Tomas Pajonk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接