someone
someone

Reputation: 495

How to add a DataTemplate to CollectionContainer?

Here is my specific scenario.

The Window resources code:

...
<Window.Resources>
    <ResourceDictionary>
        <CollectionViewSource x:Key="AdditionalStringData" Source="{Binding ViewModelObservableCollection_String}"/>
        <CollectionViewSource x:Key="AdditionalCustomObjectData" Source="{Binding ViewModelObservableCollection_CustomObject}"/>
        <ResourceDictionary.MergedDictionaries>
            ...
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>
...

The part where I need to display the Collection:

...
<StackPanel>
    <ItemsControl>
        <ItemsControl.ItemsSource>
            <CompositeCollection>
                <TextBlock Text="{Binding ViewModelTextProperty}"/>
                <Button Command="{Binding ViewModelRelayCommand}">Command</Button>
                <CollectionContainer Collection="{Binding Source={StaticResource AdditionalStringData}}" />
                <CollectionContainer Collection="{Binding Source={StaticResource AdditionalCustomObjectData}}" />
            </CompositeCollection>
        </ItemsControl.ItemsSource>
    </ItemsControl>
</StackPanel>
...

The ViewModel (assume that it is binded correctly)

...
private string ViewModelTextProperty  { get; set; } = "Sample Text";
public RelayCommand ViewModelRelayCommand { ... }
private ObservableCollection<string> ViewModelObservableCollection_String { get; set; } = new ObservableCollection<string>();
private ObservableCollection<CustomObject> ViewModelObservableCollection_CustomObject { get; set; } = new ObservableCollection<CustomObject>();
...

The Class CutomObject (it may not be needed to show):

...
public class CustomObject
{
    public string firstString;
    public string secondString;

    public CustomObject()
    {
        ...
    }
    ...
}
...

Assume that the ObservableCollections has proper contents.

My question is: How can I display the collection properly? Here is the criteria:

As you can see, the content of the StackPanel is a merge of more than one Collection with different DataTemplate.

Please ask for clarification if something is not clear enough.

Upvotes: 1

Views: 963

Answers (1)

AnjumSKhan
AnjumSKhan

Reputation: 9827

  1. Use DataTrigger inside ItemTemplate to change ControlTemplate of Control used, while comparing Type. For this use a converter which would return the type.

    or,

  2. Use ContentControl as ItemTemplate.

  3. Define DataTemplate specifying DataType in it. ContentControl will automatically pick appropriate DataTemplate for its ContentTemplate.

Second Approach (Recommended)

<Window.Resources>
    <ResourceDictionary>            
        ...
        <DataTemplate DataType="{x:Type sys:String}">
            <TextBlock Background="ForestGreen" Text="{Binding .}"/>
        </DataTemplate>

        <DataTemplate DataType="{x:Type local:CustomObject}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Background="Red" Text="{Binding firstString}"/>
                <TextBlock Background="Red" Text="{Binding secondString}"/>
            </StackPanel>
        </DataTemplate>
    </ResourceDictionary>
</Window.Resources>
<ItemsControl>
... 
 <ItemsControl.ItemTemplate>
    <DataTemplate>
        <ContentControl Content="{Binding .}"/>
    </DataTemplate>
 </ItemsControl.ItemTemplate>
 ...
</ItemsControl>

Upvotes: 1

Related Questions