Mare Infinitus
Mare Infinitus

Reputation: 8182

Set Image Source depending on ViewModels Type

I have hierarchical data which I want to display inside a TreeView. All those objects have a common base class and the Bindings work with that baseclass. Now I want to show a different Image depending on the Type of the ViewModel.

Right now I have a HierachicalDataTemplate for that.

<HierarchicalDataTemplate DataType="{x:Type viewModels:ItemBaseViewModel}" ItemsSource="{Binding Children}">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="20*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100*" />
            <ColumnDefinition Width="5" />
            <ColumnDefinition Width="100*" />
            <ColumnDefinition Width="100*" />
            <ColumnDefinition Width="100*" />
        </Grid.ColumnDefinitions>

        <Image Grid.Column="0"
               Height="12"
               Source="/Client;component/Images/icon.png" />

        <TextBlock Grid.Column="2" Text="{Binding DisplayString}" />
    </Grid>
</HierarchicalDataTemplate>

What is the easiest way to display bar.png for BarViewModel and foo.png for FooViewModel? (Both of them are derived from ItemBaseViewModel)

Upvotes: 0

Views: 116

Answers (2)

nmclean
nmclean

Reputation: 7734

The easiest way is when the difference can be distinguished by a property, which can be checked through a DataTrigger. For example, if there was a TypeId property which was a string or enum with values foo and bar, a style like this could be applied to the image:

<Style TargetType="Image">
    <Setter Property="Source" Value="foo.png" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=TypeId}" Value="bar">
            <Setter Property="Source" Value="bar.png" />
        </DataTrigger>
    </Style>
</Style>

Another way is to take advantage of the fact that DataTemplate resources defined with a DataType will automatically be applied to that type. But instead of having global resources that re-implement your entire template for each type, you could place a ContentControl within your main template, with its own local resources for just the image part:

<ContentControl Grid.Column="0" Content="{Binding}">
    <ContentControl.Resources>
        <DataTemplate DataType="{x:Type viewModels:foo}">
            <Image Source="foo.png" />
        </DataTemplate>
        <DataTemplate DataType="{x:Type viewModels:bar}">
            <Image Source="bar.png" />
        </DataTemplate>
    </ContentControl.Resources>
</ContentControl>

Upvotes: 1

James
James

Reputation: 9985

Have a String ImagePath Property on your base view model and override the get accessor or set the Property in the constructor of your derived types

Upvotes: 1

Related Questions