Недопустимое исключение трансляции в UWP Treeview C# - PullRequest
0 голосов
/ 28 мая 2020

При использовании древовидной структуры, привязанной к трехуровневой иерархической коллекции (Заказ - Артикул - Расположение). Я использую DataTemplateSelector, чтобы выбрать шаблон TreeViewItem для использования. Я получаю недопустимое исключение точно так же, как в этом сообщении , когда я прокручиваю - кажется, что исключение возникает быстрее, если я прокручиваю быстрее.

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

Вот мой XAML и код для TreeView, который в настоящее время создает исключение:

<Page
x:Class="PickSheetManager.Views.PickSheetManagerPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:winui="using:Microsoft.UI.Xaml.Controls"
xmlns:model="using:PickSheetManager.Core.Models"
xmlns:behaviors="using:PickSheetManager.Behaviors"
xmlns:templateSelectors="using:PickSheetManager.TemplateSelectors"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:controls1="using:PickSheetManager.Controls"
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
xmlns:i="using:Microsoft.Xaml.Interactivity"
Style="{StaticResource PageStyle}"
behaviors:NavigationViewHeaderBehavior.HeaderMode="Never"
mc:Ignorable="d">

<Page.Resources>        
    <DataTemplate x:Key="OrderTemplate" x:DataType="model:Order">
        <winui:TreeViewItem
            AutomationProperties.Name="{x:Bind PoIDx}"
            ItemsSource="{x:Bind SKUs}" IsExpanded="True">
            <StackPanel x:Name="stack" Orientation="Horizontal">
            <i:Interaction.Behaviors>
                <ic:DataTriggerBehavior Binding ="{x:Bind NotEnoughInventory}" Value="True">
                    <ic:ChangePropertyAction TargetObject="{Binding ElementName=stack}" PropertyName="Background" Value="Red" />
                </ic:DataTriggerBehavior>
            </i:Interaction.Behaviors>
            <CheckBox IsChecked="{x:Bind IsSelected, Mode=TwoWay}" Padding="5" MinWidth="0"/>
            <TextBlock Text="PoIDx: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            <TextBlock Text="{x:Bind PoIDx}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            <TextBlock Text="Delivery: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            <TextBlock Text="{x:Bind DeliveryType}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            <TextBlock Text="Delivery: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            <TextBlock Text="{x:Bind DeliveryType}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            <TextBlock Text="Type: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            <TextBlock Text="{x:Bind OrderType}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            <TextBlock Text="Total Quantity: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            <TextBlock Text="{x:Bind TotalQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            <TextBlock Text="Printed: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            <TextBlock Text="{x:Bind IsPrinted}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            <TextBlock Text="Notes: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            <TextBox Text="{x:Bind Notes, Mode=TwoWay}" Margin="{StaticResource XXSmallTopRightBottomMargin}" Width="150"/>
        </StackPanel>
        </winui:TreeViewItem>
    </DataTemplate>        

    <DataTemplate x:Key="SKUTemplate" x:DataType="model:SKU">
        <winui:TreeViewItem
            AutomationProperties.Name="{x:Bind SKUNum}"
            ItemsSource="{x:Bind Locations}" IsExpanded="True">
            <StackPanel x:Name="stack2" Orientation="Horizontal">
                <i:Interaction.Behaviors>
                    <ic:DataTriggerBehavior Binding ="{x:Bind NotEnoughInventory}" Value="True">
                        <ic:ChangePropertyAction TargetObject="{Binding ElementName=stack2}" PropertyName="Background" Value="Yellow" />
                    </ic:DataTriggerBehavior>
                </i:Interaction.Behaviors>
                <CheckBox IsChecked="{x:Bind IsSelected, Mode=TwoWay}" Padding="5" MinWidth="0" />
                <TextBlock Text="SKU: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind SKUNum}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Needed: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind NeedQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Available: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind AvailableQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            </StackPanel>
        </winui:TreeViewItem>
    </DataTemplate>        

    <DataTemplate x:Key="LocationTemplate" x:DataType="model:Location">
        <winui:TreeViewItem
            AutomationProperties.Name="{x:Bind LocationName}"
            IsExpanded="True">
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{x:Bind IsSelected, Mode=TwoWay}" Padding="5" MinWidth="0" />
                <TextBlock Text="{x:Bind LocationName}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Pick Type: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind PickType}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Pick Quantity: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind PickQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Available Quantity: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind AvailableQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBox Text="{x:Bind Notes, Mode=TwoWay}" Margin="{StaticResource XXSmallTopRightBottomMargin}" Width="150" />
            </StackPanel>
        </winui:TreeViewItem>
    </DataTemplate>      


    <templateSelectors:SampleDataTemplateSelector x:Key="TreeViewTemplateSelector"
        OrderDetailTemplate="{StaticResource OrderTemplate}"
        SKUDetailTemplate="{StaticResource SKUTemplate}"
        LocationDetailTemplate="{StaticResource LocationTemplate}" />
</Page.Resources>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition x:Name="treeViewColumn" Width="6*" />
        <ColumnDefinition x:Name="detailViewColumn" Width="4*" />
    </Grid.ColumnDefinitions>
    <Grid Grid.Column="0">
        <Grid.RowDefinitions>
            <RowDefinition x:Name="treeViewRow" Height="8*" />
            <RowDefinition x:Name="controlRow" Height="2*" />
        </Grid.RowDefinitions>
        <ScrollViewer x:Name="WrapViewer" Grid.Row="0" Grid.Column="0" Padding="{StaticResource DetailPageMargin}">
        </ScrollViewer>
        <winui:TreeView
            x:Name="treeView"
            Grid.Row="0"
            SelectionMode="Single"
            ItemsSource="{x:Bind ViewModel.openOrders}"
            ItemTemplateSelector="{StaticResource TreeViewTemplateSelector}">
            <i:Interaction.Behaviors>
                <behaviors:TreeViewCollapseBehavior x:Name="collapseBehavior" />
                <ic:EventTriggerBehavior EventName="ItemInvoked">
                    <ic:InvokeCommandAction Command="{x:Bind ViewModel.ItemInvokedCommand}" />
                </ic:EventTriggerBehavior>
            </i:Interaction.Behaviors>
        </winui:TreeView>
    </Grid>
    <Grid Grid.Column="1">
        <Grid.RowDefinitions>
            <RowDefinition x:Name="detailViewRow" Height="4*" />
            <RowDefinition x:Name="iarRow" Height="4*" />
            <RowDefinition x:Name="controlRow2" Height="2*" />
        </Grid.RowDefinitions>
    </Grid>
</Grid>    

Привязываемая коллекция

 public ObservableCollection<Order> openOrders { get; } = new ObservableCollection<Order>();


 public async Task LoadDataAsync()
 {           
     var data2 = await OrderDataLoader.GetTreeViewDataAsync();
     foreach (var item in data2)
     {
         openOrders.Add(item);
     }                   
 }

И код DataTemplateSelector:

public class SampleDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate OrderDetailTemplate { get; set; }

    public DataTemplate SKUDetailTemplate { get; set; }

    public DataTemplate LocationDetailTemplate { get; set; }

    protected override DataTemplate SelectTemplateCore(object item)
    {
        return GetTemplate(item) ?? base.SelectTemplateCore(item);
    }

    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    {
        return GetTemplate(item) ?? base.SelectTemplateCore(item, container);
    }

    private DataTemplate GetTemplate(object item)
    {
        switch (item)
        {
            case Order order:
                return OrderDetailTemplate;
            case SKU sku:
                return SKUDetailTemplate;
            case Location location:
                return LocationDetailTemplate;
        }

        return null;
    }
}

Обновление

Я действительно пробовал две разные попытки заставить пользовательский элемент управления работать. В обоих случаях отображался только один уровень.

Попытка №1 UserControl XAML:

<UserControl
    x:Class="PickSheetManager.Controls.OrderTreeItemControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:winui="using:Microsoft.UI.Xaml.Controls"
    xmlns:model="using:PickSheetManager.Core.Models"
    xmlns:behaviors="using:PickSheetManager.Behaviors"
    xmlns:templateSelectors="using:PickSheetManager.TemplateSelectors"
    xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
    xmlns:controls1="using:PickSheetManager.Controls"
    xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
    xmlns:i="using:Microsoft.Xaml.Interactivity"
    mc:Ignorable="d">

    <UserControl.Resources>
        <DataTemplate x:Name="OrderTemplate" x:DataType="model:Order">
            <StackPanel x:Name="stack" Orientation="Horizontal">
                <i:Interaction.Behaviors>
                    <ic:DataTriggerBehavior Binding ="{x:Bind NotEnoughInventory}" Value="True">
                        <ic:ChangePropertyAction TargetObject="{Binding ElementName=stack}" PropertyName="Background" Value="Red" />
                    </ic:DataTriggerBehavior>
                </i:Interaction.Behaviors>
                <CheckBox IsChecked="{x:Bind IsSelected, Mode=TwoWay}" Padding="5" MinWidth="0"/>
                <TextBlock Text="PoIDx: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind PoIDx}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Delivery: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind DeliveryType}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Delivery: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind DeliveryType}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Type: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind OrderType}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Total Quantity: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind TotalQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Printed: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind IsPrinted}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Notes: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBox Text="{x:Bind Notes, Mode=TwoWay}" Margin="{StaticResource XXSmallTopRightBottomMargin}" Width="150"/>
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Name="SKUTemplate" x:DataType="model:SKU">            
            <StackPanel x:Name="stack2" Orientation="Horizontal">
                <i:Interaction.Behaviors>
                    <ic:DataTriggerBehavior Binding ="{x:Bind NotEnoughInventory}" Value="True">
                        <ic:ChangePropertyAction TargetObject="{Binding ElementName=stack2}" PropertyName="Background" Value="Yellow" />
                    </ic:DataTriggerBehavior>
                </i:Interaction.Behaviors>
                <CheckBox IsChecked="{x:Bind IsSelected, Mode=TwoWay}" Padding="5" MinWidth="0" />
                <TextBlock Text="SKU: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind SKUNum}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Needed: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind NeedQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Available: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind AvailableQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
            </StackPanel>            
        </DataTemplate>
        <DataTemplate x:Name="LocationTemplate" x:DataType="model:Location">
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{x:Bind IsSelected, Mode=TwoWay}" Padding="5" MinWidth="0" />
                <TextBlock Text="{x:Bind LocationName}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Pick Type: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind PickType}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Pick Quantity: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind PickQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="Available Quantity: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBlock Text="{x:Bind AvailableQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                <TextBox Text="{x:Bind Notes, Mode=TwoWay}" Margin="{StaticResource XXSmallTopRightBottomMargin}" Width="150" />
            </StackPanel>            
        </DataTemplate>
    </UserControl.Resources>

    <Grid>
        <ContentControl x:Name="MainContent"/>
    </Grid>
</UserControl>

Попытка №1 .cs

    namespace PickSheetManager.Controls
{
    public sealed partial class OrderTreeItemControl : UserControl
    {
        public OrderTreeItemControl()
        {
            this.InitializeComponent();
        }

        public Order Data
        {
            get { return (OpenOrdersBase)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }

        public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register("Data", typeof(OpenOrdersBase), typeof(OrderTreeItemControl), new PropertyMetadata(null, new PropertyChangedCallback(Data_Changed)));

        private static void Data_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue != null)
            {
                var instance = d as OrderTreeItemControl;
                if (e.NewValue is Location)
                {
                    instance.MainContent.ContentTemplate = instance.LocationTemplate;
                }
                else if (e.NewValue is SKU)
                {
                    instance.MainContent.ContentTemplate = instance.SKUTemplate;
                }
                else
                {
                    instance.MainContent.ContentTemplate = instance.OrderTemplate;
                }
            }
        }
    }
}

Попытка №1 классов модели

public class OpenOrdersBase
{
    public ObservableCollection<Order> Orders { get; } = new ObservableCollection<Order>();
}
public class Order : OpenOrdersBase
{
    public bool IsSelected { get; set; }
    public string OrderNumber { get; set; }
    public string PoIDx { get; set; }
   ...
    public ICollection<SKU> SKUs { get; set; }

}
public class SKU : OpenOrderBase
{
    public bool IsSelected { get; set; }
    public string SKUNum { get; set; }
    ...
    public ICollection<Location> Locations { get; set; }
}
public class Location : OpenOrdersBase
{
    public bool IsSelected { get; set; }
    ...
    public string Notes { get; set; }
}

Попытка № 1 Страница XAML

<DataTemplate x:Key="BaseTemplate" x:DataType="model:Order">
            <winui:TreeViewItem
                IsExpanded="False"
                ItemsSource="{x:Bind SKUs}">
                <controls1:TestControl Data="{Binding}"/>
             </winui:TreeViewItem>                        
         </DataTemplate>
...
<winui:TreeView
            x:Name="treeView"
            Grid.Row="0"
            SelectionMode="Single"
            Margin="10,10,10,10"
            ItemsSource="{x:Bind ViewModel.openOrders}"
            ItemTemplate="{StaticResource BaseTemplate}">
            <i:Interaction.Behaviors>
                <behaviors:TreeViewCollapseBehavior x:Name="collapseBehavior" />
                <ic:EventTriggerBehavior EventName="ItemInvoked">
                    <ic:InvokeCommandAction Command="{x:Bind ViewModel.ItemInvokedCommand}" />
                </ic:EventTriggerBehavior>
            </i:Interaction.Behaviors>
        </winui:TreeView>

Попытка № 2 Большая разница была в XAML UserControl и в моделях UserControl XAML

    <UserControl
    x:Class="PickSheetManager.Controls.OrderTreeItemControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:winui="using:Microsoft.UI.Xaml.Controls"
    xmlns:model="using:PickSheetManager.Core.Models"
    xmlns:behaviors="using:PickSheetManager.Behaviors"
    xmlns:templateSelectors="using:PickSheetManager.TemplateSelectors"
    xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
    xmlns:controls1="using:PickSheetManager.Controls"
    xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
    xmlns:i="using:Microsoft.Xaml.Interactivity"
    mc:Ignorable="d">

    <UserControl.Resources>

        <DataTemplate x:Name="OrderTemplate" x:DataType="model:Order">
            <winui:TreeViewItem
                AutomationProperties.Name="{x:Bind PoIDx}"
                ItemsSource="{x:Bind SKUs}"
                IsExpanded="True">
                <StackPanel x:Name="stack" Orientation="Horizontal">
                    <i:Interaction.Behaviors>
                        <ic:DataTriggerBehavior Binding ="{x:Bind NotEnoughInventory}" Value="True">
                            <ic:ChangePropertyAction TargetObject="{Binding ElementName=stack}" PropertyName="Background" Value="Red" />
                        </ic:DataTriggerBehavior>
                    </i:Interaction.Behaviors>
                    <CheckBox IsChecked="{x:Bind IsSelected, Mode=TwoWay}" Padding="5" MinWidth="0"/>
                    <TextBlock Text="PoIDx: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="{x:Bind PoIDx}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="Delivery: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="{x:Bind DeliveryType}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="Delivery: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="{x:Bind DeliveryType}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="Type: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="{x:Bind OrderType}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="Total Quantity: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="{x:Bind TotalQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="Printed: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="{x:Bind IsPrinted}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="Notes: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBox Text="{x:Bind Notes, Mode=TwoWay}" Margin="{StaticResource XXSmallTopRightBottomMargin}" Width="150"/>
                </StackPanel>
            </winui:TreeViewItem>

        </DataTemplate>
        <DataTemplate x:Name="SKUTemplate" x:DataType="model:SKU">
            <winui:TreeViewItem
                AutomationProperties.Name="{x:Bind SKUNum}"
                ItemsSource="{x:Bind Locations}"
                IsExpanded="True">
                <StackPanel x:Name="stack2" Orientation="Horizontal">
                    <i:Interaction.Behaviors>
                        <ic:DataTriggerBehavior Binding ="{x:Bind NotEnoughInventory}" Value="True">
                            <ic:ChangePropertyAction TargetObject="{Binding ElementName=stack2}" PropertyName="Background" Value="Yellow" />
                        </ic:DataTriggerBehavior>
                    </i:Interaction.Behaviors>
                    <CheckBox IsChecked="{x:Bind IsSelected, Mode=TwoWay}" Padding="5" MinWidth="0" />
                    <TextBlock Text="SKU: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="{x:Bind SKUNum}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="Needed: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="{x:Bind NeedQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="Available: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="{x:Bind AvailableQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                </StackPanel>
            </winui:TreeViewItem>
        </DataTemplate>
        <DataTemplate x:Name="LocationTemplate" x:DataType="model:Location">
            <winui:TreeViewItem
                AutomationProperties.Name="{x:Bind LocationName}"                
                IsExpanded="True">
                <StackPanel Orientation="Horizontal">
                    <CheckBox IsChecked="{x:Bind IsSelected, Mode=TwoWay}" Padding="5" MinWidth="0" />
                    <TextBlock Text="{x:Bind LocationName}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="Pick Type: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="{x:Bind PickType}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="Pick Quantity: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="{x:Bind PickQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="Available Quantity: " Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBlock Text="{x:Bind AvailableQuantity}" Margin="{StaticResource XXSmallTopRightBottomMargin}" />
                    <TextBox Text="{x:Bind Notes, Mode=TwoWay}" Margin="{StaticResource XXSmallTopRightBottomMargin}" Width="150" />
                </StackPanel>
            </winui:TreeViewItem>
        </DataTemplate>
    </UserControl.Resources>

    <Grid>
        <ContentControl x:Name="MainContent"/>
    </Grid>
</UserControl>

В код для пользовательского элемента управления Я просто обновил OpenOrdersBase до Order, поскольку я удалил наследование со всех моделей.

Наконец, XAML страницы изменился таким образом

<DataTemplate x:Key="BaseTemplate" x:DataType="model:Order">
    <controls1:TestControl Data="{Binding}"/>                                        
</DataTemplate>

1 Ответ

0 голосов
/ 01 июня 2020

Фактически, ваша попытка 1 очень близка к успеху и требует лишь незначительных изменений.

Эта проблема заключается в определении класса:

Order, SKU, Location имеют общий базовый класс OpenOperBase, что хорошо, но базовый класс должен предоставлять общее свойство, а не специальную коллекцию Order.

Попробуйте следующее:

public class OpenOrdersBase
{
    public ObservableCollection<OpenOrdersBase> Children { get; set; } = new ObservableCollection<OpenOrdersBase>();
}

В вашем классе Order и SKU есть атрибут подгруппы, извлеките их как отдельный атрибут коллекции базового класса, эффект которого будет виден позже в привязке данных.

Теперь вы можете удалить Order.SKUs и SKU.Locations.

При привязке содержимое TestControl изменять не нужно (сохраните формулировку в попытке №1), а шаблон TreeViewItem необходимо изменить DataType

<DataTemplate x:DataType="models:OpenOrdersBase" x:Key="BaseTemplate">
    <TreeViewItem ItemsSource="{x:Bind Children}">
        <controls:TestControl Data="{Binding}"/>
    </TreeViewItem>
</DataTemplate>

Наша общая идея такова:

  1. Поскольку TreeViewItem действует только как дочерний элемент TreeView.Children, метод попытки №2 нежелателен.
  2. Свойство TreeView.ItemTemplate влияет на все внутренние дочерние элементы, поэтому при привязке TreeViewItem.ItemsSource лучше привязать коллекцию базового класса, а не конкретный c тип коллекции (например, SKUs)
  3. Если вы хотите отобразить разные шаблоны, основанные на типе данных, создание UserControl и внутренняя оценка типа - возможный способ (вы уже это сделали).

Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...