2017-06-04 33 views
2

我在我的XAML和一個類MyListItem中定義了兩個ListBox。 現在,一個ListBox應該顯示名稱作爲按鈕,第二個ListBox應該將該名稱顯示爲TextBlock。兩個不同的DataTemplate

這裏有個小例子,兩個ListBox的行爲都是一樣的。

MyListItem

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> 

VIEWMODE

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); 
     } 
    } 
} 

回答

3

不幸的是,目前沒有好的方法可以在阿瓦洛尼亞做到這一點,我可以想到。最明顯的方法是將數據模板添加到<Style.Resources>集合中,並使用{StyleResource}來引用它們,但目前這不起作用。

我想你這裏有兩種選擇的時刻:

  1. 只需複製並粘貼數據模板到ItemsControl.ItemTemplate
  2. 定義數據模板的代碼,並使用{Static}引用它們。爲此,您可以使用FuncDataTemplate<>

我已經添加了一個問題來跟蹤這個問題就在這裏:https://github.com/AvaloniaUI/Avalonia/issues/1020

+0

我更新了我的代碼,就像你在第1點所說的那樣,而且它正在工作。 我只是讓你寫_ItemTemplate_。 DataTemplate和ItemTemplate有什麼區別? – EinApfelBaum

+0

與WPF中的區別大致相同:'ItemTemplate'意思是「爲每個項目單獨使用這個模板」,而將模板放入'DataTemplates'就好像將模板添加到WPF中的一個資源中,它將根據項目的類型。 – Grokys

0

您需要使用ItemsControl的,而不是ListBox和具有ItemTemplate中設置不同的每個人。

一個將指向DataTemplate(使用x:Key,而不是DataType)與TextBlock,另一個指向帶有Button的DataTemplate。

+0

我更新了我的代碼。我如何參考Window.DataTemplates? 在ItemTemplate屬性中使用StaticResource我得到一個異常。 – EinApfelBaum

+0

我剛剛注意到你寫了「Window.DataTemplates」的部分。 它應該是「Window.Resources」。 – Mishka

+0

我在Linux上使用dotnetcore和AvaloniaUI而不是WPF。沒有Window.Resource – EinApfelBaum