tags:

views:

62

answers:

3

I have a user control that hosts other controls. The way I implemented this is via data templates that define the control that should be associated with a specific view-model. These view-models have similar properties and interaction triggers. Please see XAML snippet below.

The problem with this approach is that I would have to copy-paste the data bindings if I want to support a new view-model. Is there any way of consolidating all similar data bindings and/or triggers into one template? I don't want to type/copy-paste the same data binding definitions into each control. (Yes, I know, I'm that lazy.)

<UserControl.Resources>   
    <DataTemplate DataType="{x:Type vm:SomeViewModel1}">
        <TextBlock Canvas.Left="{Binding Left}"
                   Canvas.Top="{Binding Top}"
                   RenderTransform="{Binding Transform}"
                   Height="{Binding Height}"
                   Width="{Binding Width}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter">
                    <cmd:EventToCommand Command="{Binding MouseEnterCommand}"/>
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseLeave">
                    <cmd:EventToCommand Command="{Binding MouseLeaveCommand}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBlock>
    </DataTemplate>

    <DataTemplate DataType="{x:Type vm:SomeViewModel2}">
        <Rectangle Canvas.Left="{Binding Left}"
                   Canvas.Top="{Binding Top}"
                   RenderTransform="{Binding Transform}"
                   Height="{Binding Height}"
                   Width="{Binding Width}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter">
                    <cmd:EventToCommand Command="{Binding MouseEnterCommand}"/>
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseLeave">
                    <cmd:EventToCommand Command="{Binding MouseLeaveCommand}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Rectangle>
    </DataTemplate>

    <DataTemplate DataType="{x:Type vm:SomeViewModel3}">
        <Button Canvas.Left="{Binding Left}"
                Canvas.Top="{Binding Top}"
                RenderTransform="{Binding Transform}"
                Height="{Binding Height}"
                Width="{Binding Width}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter">
                    <cmd:EventToCommand Command="{Binding MouseEnterCommand}"/>
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseLeave">
                    <cmd:EventToCommand Command="{Binding MouseLeaveCommand}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </DataTemplate>

    <DataTemplate DataType="{x:Type vm:SomeViewModel4}">
       <!-- Do not want copy-paste code here... -->
    </DataTemplate>
</UserControl.Resources>
A: 

What about putting the triggers into a resource and associating them with your controls. Or use a custom base class for your DataTemplates.

Ruedi Steinmann
I'm not really an expert in XAML. Do you have any code snippet available to illustrate that?
noob_lurker
A: 

Please check this link.

http://stackoverflow.com/questions/1665267/datatemplate-datatypecollectionentity

Avatar
I think that's for a different problem altogether. That's for a list of items. My problem is dealing with objects of similar traits.
noob_lurker
Hi, this fits in your case as well. You'll have those VM's whom all want to share the same template.
Avatar
+1  A: 

You can use common style, and put both your properties and triggers (which are also properties) inside this style, look at this StackOverflow question for more details.

Amittai Shapira
I think you're correct. Although I still do not know how to do this in detail, at least I now know the general direction. Thanks.
noob_lurker