两个不同的 DataTemplate
Two different DataTemplate
我在 XAML 和一个 Class MyListItem 中定义了两个列表框。
现在,一个 ListBox 应将名称显示为按钮,第二个 ListBox 应将名称显示为 TextBlock。
这里有一个小例子,两个 ListBox 的行为相同。
我的列表项
public class MyListItem
{
private string _name;
public string Name
{
get{return _name;}
set{_name = value;}
}
}
XAML
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataTemplate.Views.MainWindow"
xmlns:viewsmodels="clr-namespace:DataTemplate.ViewModels;assembly=DataTemplate"
xmlns:dt="clr-namespace:DataTemplate;assembly=DataTemplate"
Title="DataTemplate" Width="700">
<Window.DataContext>
<viewsmodels:MainWindowViewModel />
</Window.DataContext>
<Grid ColumnDefinitions="250,250,250">
<ItemsControl Grid.Column="1" Items="{Binding List2}">
<ItemsControl.DataTemplates>
<DataTemplate DataType="{x:Type dt:MyListItem}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ItemsControl.DataTemplates>
</ItemsControl>
<ItemsControl Grid.Column="2" Items="{Binding List3}">
<ItemsControl.DataTemplates>
<DataTemplate DataType="{x:Type dt:MyListItem}">
<Button Content="{Binding Name}"/>
</DataTemplate>
</ItemsControl.DataTemplates>
</ItemsControl>
</Grid>
</Window>
查看模式
public class MainWindowViewModel
{
public ObservableCollection<MyListItem> List1 { get; set; }
public ObservableCollection<MyListItem> List2 { get; set; }
public ObservableCollection<MyListItem> List3 { get; set; }
public MainWindowViewModel()
{
List1 = new ObservableCollection<MyListItem>();
List2 = new ObservableCollection<MyListItem>();
List3 = new ObservableCollection<MyListItem>();
Random rand = new Random();
for (int i = 0; i < rand.Next(1, 20); i++)
{
MyListItem mli = new MyListItem();
mli.Name = "ListItem" + i;
List1.Add(mli);
}
for (int i = 0; i < rand.Next(1, 20); i++)
{
MyListItem mli = new MyListItem();
mli.Name = "ListItem" + i;
List2.Add(mli);
}
for (int i = 0; i < rand.Next(1, 20); i++)
{
MyListItem mli = new MyListItem();
mli.Name = "ListItem" + i;
List3.Add(mli);
}
}
}
您需要使用 ItemsControl 而不是 ListBox,并为它们分别设置不同的 ItemTemplate。
一个将指向带有 TextBlock 的 DataTemplate(使用 x:Key,而不是 DataType),另一个将指向带有 Button 的 DataTemplate。
不幸的是,目前我能想到的在 Avalonia 中没有好的方法可以做到这一点。最明显的方法是将数据模板添加到 <Style.Resources>
集合并使用 {StyleResource}
来引用它们,但这目前不起作用。
我想你现在有两个选择:
- 只需将数据模板复制并粘贴到
ItemsControl.ItemTemplate
- 在代码中定义数据模板并使用
{Static}
引用它们。为此,您可以使用 FuncDataTemplate<>
我在这里添加了一个问题来跟踪这个问题:https://github.com/AvaloniaUI/Avalonia/issues/1020
我在 XAML 和一个 Class MyListItem 中定义了两个列表框。 现在,一个 ListBox 应将名称显示为按钮,第二个 ListBox 应将名称显示为 TextBlock。
这里有一个小例子,两个 ListBox 的行为相同。
我的列表项
public class MyListItem
{
private string _name;
public string Name
{
get{return _name;}
set{_name = value;}
}
}
XAML
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataTemplate.Views.MainWindow"
xmlns:viewsmodels="clr-namespace:DataTemplate.ViewModels;assembly=DataTemplate"
xmlns:dt="clr-namespace:DataTemplate;assembly=DataTemplate"
Title="DataTemplate" Width="700">
<Window.DataContext>
<viewsmodels:MainWindowViewModel />
</Window.DataContext>
<Grid ColumnDefinitions="250,250,250">
<ItemsControl Grid.Column="1" Items="{Binding List2}">
<ItemsControl.DataTemplates>
<DataTemplate DataType="{x:Type dt:MyListItem}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ItemsControl.DataTemplates>
</ItemsControl>
<ItemsControl Grid.Column="2" Items="{Binding List3}">
<ItemsControl.DataTemplates>
<DataTemplate DataType="{x:Type dt:MyListItem}">
<Button Content="{Binding Name}"/>
</DataTemplate>
</ItemsControl.DataTemplates>
</ItemsControl>
</Grid>
</Window>
查看模式
public class MainWindowViewModel
{
public ObservableCollection<MyListItem> List1 { get; set; }
public ObservableCollection<MyListItem> List2 { get; set; }
public ObservableCollection<MyListItem> List3 { get; set; }
public MainWindowViewModel()
{
List1 = new ObservableCollection<MyListItem>();
List2 = new ObservableCollection<MyListItem>();
List3 = new ObservableCollection<MyListItem>();
Random rand = new Random();
for (int i = 0; i < rand.Next(1, 20); i++)
{
MyListItem mli = new MyListItem();
mli.Name = "ListItem" + i;
List1.Add(mli);
}
for (int i = 0; i < rand.Next(1, 20); i++)
{
MyListItem mli = new MyListItem();
mli.Name = "ListItem" + i;
List2.Add(mli);
}
for (int i = 0; i < rand.Next(1, 20); i++)
{
MyListItem mli = new MyListItem();
mli.Name = "ListItem" + i;
List3.Add(mli);
}
}
}
您需要使用 ItemsControl 而不是 ListBox,并为它们分别设置不同的 ItemTemplate。
一个将指向带有 TextBlock 的 DataTemplate(使用 x:Key,而不是 DataType),另一个将指向带有 Button 的 DataTemplate。
不幸的是,目前我能想到的在 Avalonia 中没有好的方法可以做到这一点。最明显的方法是将数据模板添加到 <Style.Resources>
集合并使用 {StyleResource}
来引用它们,但这目前不起作用。
我想你现在有两个选择:
- 只需将数据模板复制并粘贴到
ItemsControl.ItemTemplate
- 在代码中定义数据模板并使用
{Static}
引用它们。为此,您可以使用FuncDataTemplate<>
我在这里添加了一个问题来跟踪这个问题:https://github.com/AvaloniaUI/Avalonia/issues/1020