Reputation: 495
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 ObservableCollection
s has proper contents.
My question is: How can I display the collection properly? Here is the criteria:
ViewModelObservableCollection_String
items) are TextBlocks. Its text should be the value of the individual item of ViewModelObservableCollection_String
.ViewModelObservableCollection_CustomObject
items) are TextBoxes. Its text should be the value of the individual item of ViewModelObservableCollection_CustomObject
(concatenation of firstString
and secondString
).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
Reputation: 9827
Use DataTrigger
inside ItemTemplate
to change ControlTemplate
of Control
used, while comparing Type
. For this use a converter which would return the type.
or,
Use ContentControl
as ItemTemplate
.
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