按类型更改xaml模板

时间:2012-11-12 13:06:15

标签: wpf xaml mvvm datatemplate

下面是一个DataTemplate,它定义了一个条带if if命令(带图像的按钮),用于联系客户端。目前为电话联系人定义了几个命令,所以我想将其重用于其他类型的联系方式(电子邮件等)

它和它背后的视图模型的设计方式,只有两件事需要改变才能做到这一点:

  1. ContactCommand按钮的图像和工具提示
  2. 整个最后一个按钮
  3. 似乎最可重用的方法是让整个按钮本身就是一个DataTemplate,其DataType定义如本文底部所示,但我并不知道原始DataTemplate将如何使用它。我也从未使用过DataTemplateSelector,尽管听起来很有希望。

    最好的方法是什么?代码看起来怎么样?

    干杯,
    Berryl

    当前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>
    

    对于RACHEL

    修订了具有隐式数据模板的按钮

    <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>
    {
        ...
    }
    

    对象模型

    public class PcmShellVm<TCm> : SatelliteViewModel<Party, HashSet<PartyContactMechanism>> 
        where TCm : ContactMechanism
    {
        // commands...
    }
    
    public class TelephoneNumberPcmShellVm : PcmShellVm<Telephone>
    {
        ...
    }
    
    public class EmailPcmShellVm : PcmShellVm<Email>
    {
        ...
    }
    

1 个答案:

答案 0 :(得分:2)

您最后一个代码块中的DataTemplate无效,因为您将DataTemplate放入Button.Content。如果您将其放在<Button.Resources>中,那么提供Button.Content类型为CmTypes:TelecomNumberPcmShellVm

的情况应该有效

此外,您需要切换到Image.ToolTip以向图片添加工具提示,因为Button.ToolTip不是DataTemplate的有效属性

<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>
</Button>

如果您确实想要设置Button.ToolTip而不是Image.ToolTip,那么您可能需要在DataTrigger中设置Button.Style。通常对于这种情况,我有一个返回typeof(value)的转换器,所以我的DataTrigger看起来像这样:

<DataTrigger Binding="{Binding Converter={StaticResource ObjectToTypeConverter}}" 
             Value="{x:Type CmTypes:TelecomNumberPcmShellVm}">
    <Setter Property="ToolTip" ... />
</DataTrigger>

这也可用于设置Button.ContentTemplate,而不是使用如上所示的隐式数据模板。