Набор инструментов сообщества UWP MasterDetailsView не привязывается должным образом

Я пытался реализовать MasterDetailsView из набора инструментов сообщества UWP, но без особого успеха. Я отразил исходный код SampleApp с моими собственными классами и не смог получить список, который я использовал для отображения на панели Master или Details. Наконец, я попытался создать новый проект в VS и точно скопировать исходный код, указанный в SampleApp, используя тот же класс электронной почты, что и в Sample App. Несмотря на то, что все копирует идеально, я получаю те же результаты.

Я заметил несколько ошибок привязки (показанных ниже) в окне вывода VS, которые указывают на то, что это проблема привязки, но, насколько я могу видеть, я следовал обычному формату привязки, который я использовал в других приложениях и с другими контролирует.

Пример ошибки:

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')

Есть по крайней мере еще один вопрос с этой же проблемой в StackOverflow (я думал, что видел больше), но нет принятых ответов, и ни один из непринятых ответов не решил проблему для меня. Я также попробовал проверить Образец приложения Toolkit исходный код на github, чтобы узнать, не пропал ли исходный код, указанный в SampleApp, но все там идентично.

Я вставляю свой исходный код ниже, может ли кто-нибудь помочь определить, что с этим не так?

Предыдущий вопрос (нет принятых ответов)

представление Master-Details в 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; }
    }    
}

person Keven M    schedule 05.03.2020    source источник


Ответы (2)


Это не обязательная проблема, а проблема с отрисовкой.

Во время рендеринга его невозможно рендерить, потому что вам не хватает какого-то важного контента. Но поскольку мы используем ключевое слово Binding вместо x:Bind, вы не получите сообщение об ошибке при обнаружении ошибки рендеринга во время выполнения, а вместо этого прервите рендеринг элемента электронной почты, поэтому мы увидим пустое поле.

Недостающее содержимое выглядит следующим образом:

  1. Кисть: Brush-Blue-01
  2. Поле класса: Thumbnail

Brush-Blue-01 появляется в MasterDetailsView.ItemTemplate, если вы не определяете эту кисть, вам необходимо заменить или удалить ее.

Thumbnail появляется в MasterDetailsView.DetailsTemplate, это должно быть свойство в классе Email, если вы не определили его, что также вызовет исключение. Таким образом, вы можете рассмотреть возможность удаления элемента управления, который ссылается на это свойство, или усовершенствовать определение класса Email.

person Richard Zhang - MSFT    schedule 06.03.2020
comment
Я добавил и то, и другое перед публикацией, извините, я забыл, что они не были частью кода в SampleApp. Я только что отредактировал вопрос, чтобы показать класс электронной почты, который я использую, с включенным эскизом, и у меня есть Brush-Blue-01, добавленный в App.xaml (не хотел публиковать так много кода). Я также просто попытался запустить его снова после удаления их и получил те же результаты. Есть ли что-нибудь еще, что могло вызвать это? - person Keven M; 06.03.2020
comment
Привет, пожалуйста, измените ключевое слово привязки MasterDetailsView.ItemsSource на x:Bind, которое можно привязать во время компиляции. - person Richard Zhang - MSFT; 06.03.2020
comment
На самом деле я как раз собирался опубликовать здесь, что я только что понял это. Необходимо использовать x:Bind вместо Binding, но также требуется x:DataType на <DataTemplate>. Я пробовал это раньше, но только что понял, что когда я это сделал, я попробовал только в первом разделе (ItemsTemplate), а не во втором (DetailTemplate). - person Keven M; 06.03.2020
comment
В общем, для предопределенных коллекций использование x:Bind более полезно для программ для поиска связанных объектов, поэтому вы можете изменить код, чтобы помочь вам его использовать. - person Richard Zhang - MSFT; 06.03.2020

В ходе обсуждения с Ричардом Чжаном (комментарии выше) я выяснил, в чем заключалась проблема. На самом деле проблема состояла из двух компонентов, которые взаимосвязаны друг с другом.

  1. Приложение Community Toolkit SampleApp использовало {Binding}, а не {x:Bind}, что потребовало бы установки ItemsSource в файле кода, а также в XAML.
  2. Кроме того, DataTemplate в XAML также необходимо было установить {x:DataType}.

Примечание. Для правильной работы {x:Bind} ItemsSource (в данном случае List<Email>) должен быть глобальным членом; он должен быть объявлен внутри класса, но вне каких-либо функций. Он может быть определен / изменен внутри функции, но начальное объявление должно быть на уровне класса (я обычно помещаю их в качестве первого элемента в классе сразу после открывающих скобок).

Я пробовал каждый из них по отдельности, прежде чем опубликовать вопрос, но не вместе в одно и то же время. Как только я внес оба этих изменения (и в оба 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>
person Keven M    schedule 06.03.2020