如何在WPF中使用动态绑定制作通用模板

时间:2018-12-20 16:57:01

标签: wpf xaml data-binding controltemplate

我在WPF中使用各自的控件模板创建了不同的控件,它们的样式几乎相似,但绑定不同,如下所示,这消除了额外的混乱。我正在寻找一种使公用ControlTemplate以及使绑定动态化的方法。

ControlTemplate用于MasterRuleLayout控件

<ControlTemplate TargetType="{x:Type local:MasterRuleLayout}">
    <StackPanel>
        <Image  
            Style="{StaticResource MasterLayoutImageStyle}"
            DataContext="{Binding CommonAggregate.SelectedRule}">
        </Image>
        <TextBox
            Text="{Binding CommonAggregate.SelectedRule.Name}">
            <TextBox.Style>
                <Style TargetType="TextBox">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding CommonAggregate.SelectedRule.Parent}" 
                                     Value="{x:Null}">
                            <Setter Property="IsEnabled" Value="False" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBox.Style>
        </TextBox>
    </StackPanel>
</ControlTemplate>

ControlTemplate用于MasterEntityLayout控件

<ControlTemplate TargetType="{x:Type local:MasterEntityLayout}">
    <StackPanel>
        <Image  
            Style="{StaticResource MasterLayoutImageStyle}"
            DataContext="{Binding CommonAggregate.SelectedEntityItem}">
        </Image>
        <TextBox
            Text="{Binding CommonAggregate.SelectedEntityItem.Name}">               
        </TextBox>
    </StackPanel>
</ControlTemplate>

1 个答案:

答案 0 :(得分:1)

绑定需要依赖属性,以在模板绑定中的属性与要绑定到的视图模型中的属性之间形成“胶水”。这意味着您的选择是:1)使用TemplateBinding通过模板化父级中的现有属性进行绑定; 2)创建缺少任何其他属性的自定义控件,或3)使用附加属性:

<Window.Resources>
    <ControlTemplate x:Key="MyTemplate" TargetType="{x:Type Control}">
        <TextBlock Text="{Binding Path=(local:AttachedProps.Name), Mode=OneWay,
            RelativeSource={RelativeSource TemplatedParent}}" />
    </ControlTemplate>
</Window.Resources>

<Control Template="{StaticResource MyTemplate}"
    local:AttachedProps.Name="{Binding MyViewModelName, Mode=OneWay}" />

然后您将自己创建附加属性,如下所示:

public static class AttachedProps
{
    #region Name

    public static string GetName(DependencyObject obj)
    {
        return (string)obj.GetValue(NameProperty);
    }

    public static void SetName(DependencyObject obj, string value)
    {
        obj.SetValue(NameProperty, value);
    }

    public static readonly DependencyProperty NameProperty =
        DependencyProperty.RegisterAttached("Name", typeof(string),
        typeof(AttachedProps), new PropertyMetadata(String.Empty));

    #endregion Name
}