EinApfelBaum
EinApfelBaum

Reputation: 157

Two different DataTemplate

I have two ListBoxs defined in my XAML and one Class MyListItem. Now one ListBox should display the name as button and the second ListBox should display the name as a TextBlock.

Here a little example, both ListBoxs behave the same.

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

Upvotes: 2

Views: 2210

Answers (2)

Grokys
Grokys

Reputation: 16546

Unfortunately there's currently no good way to do this in Avalonia that I can think of. The most obvious way would be to add the data templates to a <Style.Resources> collection and use {StyleResource} to reference them, but this doesn't work currently.

I think you have two alternatives here for the moment:

  1. Just copy and paste the data templates into the ItemsControl.ItemTemplate
  2. Define the data templates in code and reference them using {Static}. For this you can use FuncDataTemplate<>

I've added an issue to track this problem here: https://github.com/AvaloniaUI/Avalonia/issues/1020

Upvotes: 3

Mishka
Mishka

Reputation: 516

You need to use ItemsControl instead of ListBox and have ItemTemplate set differently for each of them.

One will point to DataTemplate(using x:Key, not DataType) with TextBlock, and the other to DataTemplate with Button.

Upvotes: 0

Related Questions