【发布时间】:2021-01-19 05:46:56
【问题描述】:
编辑 2: 根据 Peter Duniho 的建议,我将用一个更简单的示例替换我的问题的原始文本和对我原始代码的引用。
我正在开发一个 WinUI 3 应用程序。主窗口有一个TreeView,其层次结构如下:顶级项的类型为CarMake,每个CarMake 可以有0 个或多个CarModel 子项。该窗口有一个名为Cars 的ObservableCollection<CarMake> 属性,它是顶级CarMakes 的源,每个CarMake 都有一个ObservableCollection<CarModel> 属性CarModels,它是@987654336 中其子级的源@。
下面分别是CarMakeView 和CarModelView 类型的XAML 定义:
<StackPanel Orientation="Horizontal"
Padding="12"
x:Class="Cars.View.CarMakeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBlock Text="{x:Bind CarMake.Name}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal"
x:Class="Cars.View.CarModelView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<TextBlock Text="{x:Bind Path=CarModel.Name}" />
</StackPanel>
CarMake.cs 和CarModel.cs:
namespace Cars.Model
{
public class CarMake
{
public string? Name { get; set; }
public ObservableCollection<CarModel> CarModels { get; set; } = new();
}
}
namespace Cars.Model
{
public class CarModel
{
public string? Name { get; set; }
}
}
这是MainWindow 的 XAML。
<Window
<!-- imports etc. -->
>
<Grid>
<Grid.Resources>
<DataTemplate x:Key="CarMakeTemplate" x:DataType="model:CarMake">
<TreeViewItem ItemsSource="{x:Bind CarModels}">
<viewModel:CarMakeView CarMake="{Binding}"/>
</TreeViewItem>
</DataTemplate>
<DataTemplate x:Key="CarModelTemplate" x:DataType="model:CarModel">
<TreeViewItem>
<viewModel:CarModelView CarModel="{Binding}"/>
</TreeViewItem>
</DataTemplate>
<utility:CarItemSelector
x:Key="CarItemSelector"
CarMakeTemplate="{StaticResource CarMakeTemplate}"
CarModelTemplate="{StaticResource CarModelTemplate}" />
</Grid.Resources>
<TextBlock/>
<TreeView Grid.Row="1" ItemsSource="{x:Bind Cars}"
ItemTemplateSelector="{StaticResource CarItemSelector}">
</TreeView>
</Grid>
</Window>
最后是MainWindow 的代码隐藏。请注意,我使用硬编码的CarMake 集合初始化了Cars 属性,每个集合都关联了CarModels。这定义了我们期望在 UI 中看到的数据层次结构:
public sealed partial class MainWindow : Window
{
public ObservableCollection<CarMake> Cars { get; set; } =
new ()
{
new CarMake { Name = "Chevrolet", CarModels = { new CarModel { Name = "Camaro" }, new CarModel { Name = "Blazer" }, new CarModel { Name = "Beretta" } } },
new CarMake { Name = "Land Rover", CarModels = { new CarModel { Name = "Discovery" }, new CarModel { Name = "LR3" }, new CarModel { Name = "Range Rover" } } },
new CarMake { Name = "Quadra", CarModels = { new CarModel { Name = "Turbo-R 740" }, new CarModel { Name = "Type-66 Avenger" }} },
new CarMake { Name = "Powell Motors", CarModels = { new CarModel { Name = "The Homer" }}}
};
public MainWindow()
{
this.InitializeComponent();
}
}
这是我所期望的:在 UI 中,汽车模型应该出现在汽车品牌的视觉子代中,它们在代码中被分配给它们。因此,例如,“The Homer”,并且只有“The Homer”,应该出现在“Powell Motors”的子代中。
问题出在此:启动应用程序并展开和折叠至少一个汽车品牌项目后,汽车模型开始显示在错误的汽车品牌下方。例如,“The Homer”汽车模型可能出现在“Chevrolet”下,而不是“Powell Motors”下。每当一个顶级汽车制造项目被折叠然后展开时,一组全新的汽车模型就会出现在它的下面,显然是从它的邻居那里随机采购的。这几乎就像 UI 框架只是在玩弄 CarModels 并将它们贴在任何感觉像的 CarMake 下,而不是尊重数据定义的层次结构。
我想知道的:我需要进行哪些更改才能使汽车型号名称仅出现在 UI 中指定的父级下方?另外,我想了解导致此问题的原因。
我知道 WinUI 3 现在绝对是最前沿的,所以我的一部分希望它是框架中的一个错误,而不是我做过的事情。我试图包含我认为与问题相关的所有代码,但如果问题出在其他地方here's a link to the GitHub repo - 它非常少,只有足够的代码来说明问题,并且只需几秒钟即可在 Visual Studio 中构建。
【问题讨论】:
-
WinUI3 团队在这里积极回答问题:WinUI3 issues
-
谢谢罗伊。如果共识是 WinUI 的错误而不是我做错的事情,我肯定会在那里打开一个问题。
-
“我对此感到非常困惑,以至于我什至不知道从哪里开始调试它” -- 步骤 #1:创建一个 @987654323 @。另见How to debug small programs。阅读How to Ask,了解有关如何以清晰、可回答的方式提出问题的更多信息。
标签: c# xaml uwp treeview winui-3