UWP 社区工具包 MasterDetailsView 未按预期绑定

UWP Community Toolkit MasterDetailsView not binding as expected

我一直在尝试从 UWP 社区工具包实现 MasterDetailsView,但收效甚微。我用我自己的 classes 镜像了 SampleApp 源代码,但无法获得我用来在主窗格或详细信息窗格中显示的列表。最后,我尝试在 VS 中创建一个新项目,并使用与示例应用相同的电子邮件 class 完全复制示例应用中列出的源代码。尽管完美地复制了所有内容,但我得到了相同的结果。

我注意到 VS 的输出 window 中有几个绑定错误(如下所示),表明这是一个绑定问题,但据我所知,我遵循的是正常的绑定格式在其他应用程序和其他控件上使用过。

错误示例:

Error: BindingExpression path error: 'Emails' property not found on 'MasterDetailsTest.MainPage'. BindingExpression: Path='Emails' DataItem='MasterDetailsTest.MainPage'; target element is 'Microsoft.Toolkit.Uwp.UI.Controls.MasterDetailsView' (Name='null'); target property is 'ItemsSource' (type 'Object')

在 Whosebug 上至少有一个与此相同问题的其他问题(我想我已经看到了更多),但没有接受的答案,并且 none 的未接受的答案为我解决了这个问题。我还尝试检查 github 上的 Toolkit Sample App 源代码,看看 SampleApp 中是否缺少列出的源代码,但那里的所有内容都是相同的。

我在下面粘贴了我的源代码,有人可以帮助确定这里出了什么问题吗?

上一个问题(没有被接受的答案)

Master-Details view in UWP Community Toolkit

MainPage.xaml:

<Page
    x:Class="MasterDetailsTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MasterDetailsTest"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <controls:MasterDetailsView BackButtonBehavior="Automatic" ItemsSource="{Binding Emails}" NoSelectionContent="Select an item to view" CompactModeThresholdWidth="720">
        <controls:MasterDetailsView.ItemTemplate>
            <DataTemplate>
                <StackPanel Margin="8,0">
                    <TextBlock Text="{Binding From}" Style="{ThemeResource SubtitleTextBlockStyle}" />
                    <TextBlock Text="{Binding Subject}" Style="{ThemeResource BodyTextBlockStyle}" Foreground="{ThemeResource Brush-Blue-01}" MaxLines="1" />
                    <TextBlock Text="{Binding Body}" Style="{ThemeResource BodyTextBlockStyle}" Opacity="0.6" MaxLines="1" />
                </StackPanel>
            </DataTemplate>
        </controls:MasterDetailsView.ItemTemplate>
        <controls:MasterDetailsView.DetailsTemplate>
            <DataTemplate>
                <RelativePanel Margin="24">
                    <controls:ImageEx x:Name="FromEllipse" Source="{Binding Thumbnail}" Width="50" Height="50" CornerRadius="999" />
                    <TextBlock Text="{Binding From}" Style="{ThemeResource SubtitleTextBlockStyle}" RelativePanel.RightOf="FromEllipse" Margin="12,-6,0,0" />
                    <TextBlock x:Name="SubjectLine" Text="{Binding Subject}" Style="{ThemeResource BodyTextBlockStyle}" RelativePanel.Below="FromEllipse" Margin="0,12,0,0" />
                    <TextBlock x:Name="Body" Text="{Binding Body}" Style="{ThemeResource BodyTextBlockStyle}" TextWrapping="Wrap" RelativePanel.Below="SubjectLine" Margin="0,12,0,0" />
                </RelativePanel>
            </DataTemplate>
        </controls:MasterDetailsView.DetailsTemplate>
        <controls:MasterDetailsView.NoSelectionContentTemplate>
            <DataTemplate>
                <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                    <SymbolIcon Symbol="Mail" RenderTransformOrigin="0.5,0.5">
                        <SymbolIcon.RenderTransform>
                            <CompositeTransform ScaleX="2" ScaleY="2" />
                        </SymbolIcon.RenderTransform>
                    </SymbolIcon>
                    <TextBlock Text="{Binding}" FontSize="24" Margin="0,12" />
                </StackPanel>
            </DataTemplate>
        </controls:MasterDetailsView.NoSelectionContentTemplate>
        <controls:MasterDetailsView.MasterCommandBar>
            <CommandBar>
                <AppBarButton Icon="Back" Label="Back" />
                <AppBarButton Icon="Forward" Label="Forward" />
                <CommandBar.Content>
                    <TextBlock Margin="12,14">
                            <Run Text="{Binding Emails.Count}" />
                            <Run Text="Items" />
                    </TextBlock>
                </CommandBar.Content>
            </CommandBar>
        </controls:MasterDetailsView.MasterCommandBar>
        <controls:MasterDetailsView.DetailsCommandBar>
            <CommandBar>
                <AppBarButton Icon="MailReply" Label="Reply" />
                <AppBarButton Icon="MailReplyAll" Label="Reply All" />
                <AppBarButton Icon="MailForward" Label="Forward" />
            </CommandBar>
        </controls:MasterDetailsView.DetailsCommandBar>
    </controls:MasterDetailsView>
</Page>

MainPage.xaml.cs:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace MasterDetailsTest
{
    public sealed partial class MainPage : Page
    {
        List<Email> Emails = new List<Email>
        {            
            new Email {From = "Steve Johnson", Subject = "Lunch Tomorrow", Body = "Are you available for lunch tomorrow? A client would like to discuss a project with you." },
            new Email { From = "Becky Davidson", Subject = "Kids game", Body = "Don't forget the kids have their soccer game this Friday. We have to supply end of game snacks." },
            new Email { From = "OneDrive", Subject = "Check out your event recap", Body = "Your new album.\r\nYou uploaded some photos to yuor OneDrive and automatically created an album for you." },
            new Email { From = "Twitter", Subject = "Follow randomPerson, APersonYouMightKnow", Body = "Here are some people we think you might like to follow:\r\n.@randomPerson\r\nAPersonYouMightKnow" },
        };

        public MainPage()
        {
            this.InitializeComponent();
            DataContext = this;
        }
    }
}

Email.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MasterDetailsTest
{
    public class Email
    {
        public string From { get; set; }
        public string Subject { get; set; }
        public string Body { get; set; }
        public Uri Thumbnail { get; set; }
    }    
}

这不是绑定问题,而是呈现问题。

在渲染过程中,由于缺少一些关键内容而无法渲染。但是因为我们使用的是 Binding 关键字而不是 x:Bind,当你在运行时遇到渲染错误时你不会得到错误,而是中止渲染 Email 项目,所以我们会看到一片空白。

缺失内容如下:

  1. 笔刷:Brush-Blue-01
  2. Class 字段:Thumbnail

Brush-Blue-01出现在MasterDetailsView.ItemTemplate,如果你没有定义这个画笔,那么你需要替换或删除它。

Thumbnail出现在MasterDetailsView.DetailsTemplate,应该是Emailclass中的一个属性,如果不定义,也会导致异常。所以可以考虑删除引用这个属性的控件,或者完善Emailclass.

的定义

通过与 Richard Zhang 的讨论(以上评论),我发现了这个问题的全部内容。这个问题实际上有两个组成部分,两者相互关联。

  1. Community Toolkit SampleApp 使用 {Binding} 而不是 {x:Bind},这需要在代码文件和 XAML 中设置 ItemsSource
  2. 此外,XAML中的DataTemplate也需要设置{x:DataType}

注意: 要使 {x:Bind} 正常工作,ItemsSource(在本例中为 List<Email>)必须是全局成员;它必须在 class 内声明,但在任何函数之外。它可以是函数中的 defined/manipulated,但初始声明需要在 class 级别(我通常将它们放在 class 中的第一件事,紧跟在左括号之后) .

我在发布问题之前分别尝试了每一个,但没有同时尝试过。一旦我进行了这两项更改(以及 DataTemplate 部分),一切都按预期进行。

为了将来参考,下面粘贴了正确的 XAML 代码:

<controls:MasterDetailsView BackButtonBehavior="Automatic" ItemsSource="{x:Bind inbox}" NoSelectionContent="Select an item to view" CompactModeThresholdWidth="720">
    <controls:MasterDetailsView.ItemTemplate>
        <DataTemplate x:DataType="local:Email">
            <StackPanel Margin="8,0">
                <TextBlock Text="{x:Bind From}" Style="{ThemeResource SubtitleTextBlockStyle}" />
                <TextBlock Text="{x:Bind Subject}" Style="{ThemeResource BodyTextBlockStyle}" Foreground="{ThemeResource Brush-Blue-01}" MaxLines="1" />
                <TextBlock Text="{x:Bind Body}" Style="{ThemeResource BodyTextBlockStyle}" Opacity="0.6" MaxLines="1" />
            </StackPanel>
        </DataTemplate>
    </controls:MasterDetailsView.ItemTemplate>
    <controls:MasterDetailsView.DetailsTemplate>
        <DataTemplate x:DataType="local:Email">
            <RelativePanel Margin="24">
                <controls:ImageEx x:Name="FromEllipse" Source="{x:Bind Thumbnail}" Width="50" Height="50" CornerRadius="999" />
                <TextBlock Text="{x:Bind From}" Style="{ThemeResource SubtitleTextBlockStyle}" RelativePanel.RightOf="FromEllipse" Margin="12,-6,0,0" />
                <TextBlock x:Name="SubjectLine" Text="{x:Bind Subject}" Style="{ThemeResource BodyTextBlockStyle}" RelativePanel.Below="FromEllipse" Margin="0,12,0,0" />
                <TextBlock x:Name="Body" Text="{x:Bind Body}" Style="{ThemeResource BodyTextBlockStyle}" TextWrapping="Wrap" RelativePanel.Below="SubjectLine" Margin="0,12,0,0" />
            </RelativePanel>
        </DataTemplate>
    </controls:MasterDetailsView.DetailsTemplate>