Ben d'état

Ben Scott

~/Setting an image source using a trigger (WPF and Caliburn.Micro)

29 Jan 2014

So all I’m doing here is creating a button that has a different images depending on the enum value that is bound to the control.

The images used are linked as resources in a resource project - the build action is Resource:

Images are linked using a build action of Resource

The button’s view model (ToggleMyEnumViewModel.cs):

public class ToggleMyEnumViewModel : Screen
    MyEnum _myEnumProperty = MyEnum.Foo;

    public MyEnum MyEnumProperty
        get { return _myEnumProperty; }
            _myEnumProperty = value;
            NotifyOfPropertyChange(() => MyEnumProperty);

    public void ToggleMyThing()
        MyEnumProperty = MyEnumProperty == MyEnum.Foo
            ? MyEnum.Bar
            : MyEnum.Foo;

public enum MyEnum {
    Foo, Bar

The button’s XAML (ToggleMyEnumView.xaml):

<Button x:Class="MyNamespace.ToggleMyEnumButton"
    <Image Stretch="Uniform">
            <Style x:Key="XButtonStyle" TargetType="{x:Type Image}">
                    <DataTrigger Binding="{Binding MyEnumProperty}" Value="{x:Static local:MyEnum.Foo}">
                        <Setter Property="Image.Source" Value="pack://application:,,,/MyProject.Assets;component/Images/foo.png" />
                    <DataTrigger Binding="{Binding MyEnumProperty}" Value="{x:Static local:MyEnum.Bar}">
                        <Setter Property="Image.Source" Value="pack://application:,,,/MyProject.Assets;component/Images/bar.png" />
    <i:EventTrigger EventName="Click">
        <cal:ActionMessage MethodName="ToggleMyThing"/>


The <cal:ActionMessage MethodName="ToggleMyThing"/> part is what binds the button click to the ToggleMyThing method in the view model.

Things to note in the view’s XAML:

This is then used as a content control bound to an instance of a ToggleMyEnumViewModel. Consuming XAML:

<ContentControl x:Name="ToggleMyEnum" />

Consuming view model:

public ToggleMyEnumViewModel ToggleMyEnum { get; private set; }

public ConsumingViewModel()
    /// ...
    ToggleMyEnum = new ToggleMyEnumViewModel(); // or use an IOC factory

This isn’t exactly what I want, I would prefer to bind directly to a property on the consuming view model rather than indirectly with the ToggleMyEnumViewModel.

comments powered by Disqus