所以我有一个包含多个DataTemplates的ListView,但我不确定这是否是正确的方法。我的XAML看起来像这样:
<ListView.Resources>
<DataTemplate x:Key="ParentClass" x:DataType="local:ParentClass">
<!-- The Template -->
</DataTemplate>
<DataTemplate x:Key="ChildClass" x:DataType="local:ChildClass">
<!-- The Template -->
</DataTemplate>
</ListView.Resources>
我的课程看起来像这样:
class ParentClass {}
class ChildClass: ParentClass {}
如果对象不是ParentClass
,我怎么能确定这只会占用ChildClass
模板?我需要将它们按特殊顺序排列吗?这对XAML来说是不可能的吗?我是否需要创建第二个&#34;虚拟&#34;儿童班完全避免这个问题?
答案 0 :(得分:1)
简而言之,Windows Universal Apps不支持DataTemplate.DataType
,并且无法在没有x:Key
的情况下在资源字典中声明,因此Windows Universal Apps不支持数据类型的默认模板。 x:DataType
附加属性不会执行DataType
在WPF中执行的操作。
在Windows通用应用中,您可以将DataTemplate
内联定义为ItemsControl.ItemTemplate
或某些内容的值,或者您可以使用x:Key
在资源字典中定义它。如果要选择模板,则必须编写DataTemplateSelector
。
因此,在您的问题代码中,您正在定义模板,但没有人使用它们。
这有点拖累。
这是我的原始答案,适用于WPF。 它不适用于Windows Universal Apps ,这是此问题的实际范围。它在标签中显示win-universal-app
,但我没有阅读标签。因为它是正确的,并且可能是导致某人访问此页面的问题的答案,所以当我询问Meta是否应该删除它时,我会留在这里。
A DataTemplate
without an x:Key
property is applied to any object of the appropriate type。如果您有父类和子类的单独数据模板,它将使用最专业的数据模板。 MSDN notes that it's similar to Style.TargetType
:想象一下,如果TargetType="{x:Type Button}"
的默认样式没有自动覆盖ButtonBase
的默认样式。 混乱会随之发生!我甚至找不到明确说明情况的文件。正如Brian Kernighan所说,“你的编译器是语言的最终权威”:这就是我在快速测试中表现的方式。
如果我颠倒DataTemplate
定义的顺序,它的行为相同。如果我将ItemSubClass
DataTemplate
的定义移至Window.Resources
,它的行为也相同。
XAML:
<ItemsControl
ItemsSource="{Binding Items}"
BorderBrush="Black"
BorderThickness="1"
Margin="4"
>
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type local:ItemSubClass}">
<Grid Background="Beige">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Text="{Binding Name, StringFormat=Name: {0}}"
/>
<TextBlock
Grid.Column="1"
Text="{Binding Category, StringFormat=Category: {0}}"
/>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Item}">
<TextBlock Text="{Binding Name, StringFormat=Name: {0}}" />
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
C#:
public class Item : INotifyPropertyChanged
{
private string _name = "";
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] String propName = null)
{
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(propName));
}
}
public class ItemSubClass : Item
{
#region Category Property
private String _category = default(String);
public String Category
{
get { return _category; }
set
{
if (value != _category)
{
_category = value;
OnPropertyChanged();
}
}
}
#endregion Category Property
}
public class ViewModel
{
public ViewModel()
{
Items.Add(new Item { Name="Alan"});
Items.Add(new ItemSubClass { Name = "Bob", Category = "Whatever" });
Items.Add(new Item { Name = "Charlie" });
}
public ObservableCollection<Item> Items { get; private set; }
= new ObservableCollection<Item>();
}
截图: