两种不同的数据模板

Posted

技术标签:

【中文标题】两种不同的数据模板【英文标题】:Two different DataTemplate 【发布时间】:2017-11-05 08:29:28 【问题描述】:

我在 XAML 中定义了两个 ListBox 和一个 MyListItem 类。 现在,第一个 ListBox 应将名称显示为按钮,第二个 ListBox 应将名称显示为 TextBlock。

这是一个小例子,两个 ListBox 的行为相同。

我的列表项

public class MyListItem

    private string _name;
    public string Name
    
        getreturn _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);
        
    

【问题讨论】:

【参考方案1】:

不幸的是,目前在我能想到的 Avalonia 中没有好的方法可以做到这一点。最明显的方法是将数据模板添加到 &lt;Style.Resources&gt; 集合并使用 StyleResource 引用它们,但目前这不起作用。

我认为您目前有两种选择:

    只需将数据模板复制并粘贴到ItemsControl.ItemTemplate 在代码中定义数据模板并使用Static 引用它们。为此,您可以使用FuncDataTemplate&lt;&gt;

我在这里添加了一个问题来跟踪这个问题:https://github.com/AvaloniaUI/Avalonia/issues/1020

【讨论】:

我更新了我的代码,就像你在第 1 点说的那样。它正在工作。我只是觉得你写了 ItemTemplate 。 DataTemplate 和 ItemTemplate 有什么区别? 区别与 WPF 中的大体相同:ItemTemplate 表示“对每个项目不加条件地使用此模板”,而将模板放入 DataTemplates 就像在 WPF 中将模板添加到资源中它将根据项目的类型进行选择。【参考方案2】:

您需要使用 ItemsControl 而不是 ListBox 并为它们中的每一个设置不同的 ItemTemplate。

一个将指向带有 TextBlock 的 DataTemplate(使用 x:Key,而不是 DataType),另一个指向带有 Button 的 DataTemplate。

【讨论】:

我更新了我的代码。如何引用 Window.DataTemplates ?在 ItemTemplate 属性中使用 StaticResource 时出现异常。 我刚刚注意到你写的那部分“Window.DataTemplates”。它应该是“Window.Resources”。 我在 Linux 上使用 dotnetcore 和 AvaloniaUI,而不是 WPF。没有Window.Resource 对不起伙计,没注意到,忽略我的回答。

以上是关于两种不同的数据模板的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 刀片模板扩展了两种不同的布局

Google App Engine 和 Django 模板:为啥这两种情况不同?

使用两种不同服务的 JWT 身份验证

C++模板详解

C++ 模板详解(转)

C++模板