Below is a piece of a DataTemplate that defines a strip if commands (buttons with images) for contacting clients. Currently defined for telephone contacts, there are several more commands, so I want to reuse this for other types of contact methods (email, etc.)
The way it and the view models behind it are designed, there are only two things that need to vary to do this:
- The image and tool tip for the ContactCommand button
- The entire last button
It seems the most reusable approach would be to have the entire button be itself a DataTemplate with a DataType defined like at the bottom of this post, but I am not grokking how the original DataTemplate would consume this. I've also never used a DataTemplateSelector although that sounds promising.
What is the best approach? How would the code look?
Cheers,
Berryl
current DataTemplate
<DataTemplate x:Key="TelecomNumbersControlCommands">
<DataTemplate.Resources>
<!-- Image Style -->
<Style TargetType="{x:Type Image}">
<Setter Property="Height" Value="16" />
<Setter Property="Width" Value="16" />
</Style>
</DataTemplate.Resources>
<StackPanel Orientation="Horizontal" Margin="5,0,5,0">
<Button Command="{Binding AddCommand}" >
<Image Source="{resx:Resx Key=Img_Simplicio_Add, ResxName=Presentation.Resources.MasterDetail}" />
<Button.ToolTip>
<TextBlock>
<TextBlock.Text>
<resx:Resx Key="Subject_AddNew_ToolTip" BindingPath="SubjectVm.DisplayName" ResxName="Presentation.Resources.MasterDetail"/>
</TextBlock.Text>
</TextBlock>
</Button.ToolTip>
</Button>
<Button Command="{Binding ContactCommand}" >
<Image Source="{resx:Resx Key=Img_Telephone, ResxName=Smack.Parties.Presentation.Resources.PartyDetailView}" />
<Button.ToolTip>
<TextBlock>
<TextBlock.Text>
<resx:Resx Key="ContactCommand_Telephone_Tooltip" BindingPath="SelectedVm" ResxName="Smack.Parties.Presentation.Resources.PartyDetailView"/>
</TextBlock.Text>
</TextBlock>
</Button.ToolTip>
</Button>
</Button>
<Button Command="{Binding SetDefaultAreaCodeCommand}" >
<Image Source="{resx:Resx Img_Widget, ResxName=Presentation.Resources.MasterDetail}" />
<Button.ToolTip>
<TextBlock>
<TextBlock.Text>
<resx:Resx Key="Subject_Settings" BindingPath="SubjectVm.DisplayName" ResxName="Presentation.Resources.MasterDetail"/>
</TextBlock.Text>
</TextBlock>
</Button.ToolTip>
</Button>
...
</StackPanel>
</DataTemplate>
For RACHEL
Revised Button w/ implicit data templates
<Button Command="{Binding ContactCommand}" >
<Button.Resources>
<DataTemplate DataType="{x:Type CmTypes:TelecomNumberPcmShellVm}">
<Image Source="{resx:Resx Key=Img_Telephone, ResxName=Presentation.Resources.PartyDetailView}" >
<Image.ToolTip>
<TextBlock>
<TextBlock.Text>
<resx:Resx
Key="ContactCommand_Telephone_Tooltip"
BindingPath="SelectedVm" ResxName="Presentation.Resources.PartyDetailView"/>
</TextBlock.Text>
</TextBlock>
</Image.ToolTip>
</Image>
</DataTemplate>
</Button.Resources>
<DataTemplate DataType="{x:Type CmTypes:EmailPcmShellVm}">
<Image Source="{resx:Resx Key=Img_Email, ResxName=Presentation.Resources.PartyDetailView}" >
<Image.ToolTip>
<TextBlock>
<TextBlock.Text>
<resx:Resx
Key="ContactCommand_Email_Tooltip"
BindingPath="SelectedVm" ResxName="Presentation.Resources.PartyDetailView"/>
</TextBlock.Text>
</TextBlock>
</Image.ToolTip>
</Image>
</DataTemplate>
</Button>
Object Model
public class PcmShellVm<TCm> : SatelliteViewModel<Party, HashSet<PartyContactMechanism>>
where TCm : ContactMechanism
{
// commands...
}
public class TelephoneNumberPcmShellVm : PcmShellVm<Telephone>
{
...
}
public class EmailPcmShellVm : PcmShellVm<Email>
{
...
}
Object model
public class PcmShellVm<TCm> : SatelliteViewModel<Party, HashSet<PartyContactMechanism>>
where TCm : ContactMechanism
{
// commands...
}
public class TelephoneNumberPcmShellVm : PcmShellVm<Telephone>
{
...
}
public class EmailPcmShellVm : PcmShellVm<Email>
{
...
}
Your
DataTemplate
in your last code block doesn't work because you are putting theDataTemplate
intoButton.Content
. If you put it in<Button.Resources>
, it should work providingButton.Content
is of typeCmTypes:TelecomNumberPcmShellVm
In addition, you need to switch to an
Image.ToolTip
to add a tooltip to the Image, asButton.ToolTip
is not a valid property for yourDataTemplate
If you actually do want to set
Button.ToolTip
instead ofImage.ToolTip
, then you will probably need to set it in aDataTrigger
inButton.Style
. Usually for this kind of scenario I have a converter that returnstypeof(value)
, so myDataTrigger
looks something like this:This could also be used to set the
Button.ContentTemplate
instead of using implicit data templates as shown above.