ControlTemplate中的命令绑定与附加属性

时间:2012-10-03 20:51:48

标签: c# wpf xaml data-binding attached-properties

我正在尝试设置一个系统,允许我将一个字符串值附加到ComboBoxItem并将其显示在ComboBoxItem的内容旁边,而不必在每个ComboBoxItem中显式嵌套StackPanel或使用自定义控件。

所以我所做的是创建了一个名为“Header”的DependencyProperty并将其附加到ComboBoxItem,并且我重写了ComboBoxItem模板以包含带有TextBlock的堆栈面板,TextBlock将其Text绑定到附加的Header属性ComboBoxItem。

我遇到的问题是,运行时TextBlock中出现的唯一文本是我在元数据中设置依赖属性的默认值。此后对ComboBoxItems的附加属性的任何更改都不会反映在TextBlock中。

这是我的DependencyProperty定义:

public class AttHeader : DependencyObject
{
    public static readonly DependencyProperty HeaderProperty = DependencyProperty.RegisterAttached("Header", typeof(string), typeof(AttHeader));

    public static void SetHeader(DependencyObject d, string value)
    {
        d.SetValue(HeaderProperty, value);
    }

    public static string GetHeader(DependencyObject d)
    {
        return (string)d.GetValue(HeaderProperty);
    }
}

这是我的风格和模板:

<Style TargetType="ComboBoxItem">
    <Setter Property="OverridesDefaultStyle" Value="True"/>
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ComboBoxItem">
                <StackPanel Orientation="Horizontal">
                    <ContentPresenter />
                    <TextBlock Name="HeaderHost" Text="{Binding Path=(local:AttHeader.Header), RelativeSource={RelativeSource Self}}" />
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这是我创建一些ComboBoxItems的地方:

<ComboBox SelectedIndex="0">
    <ComboBoxItem local:AttHeader.Header="Isometric">
        <Image Source="../images/viewTypeIso.png" Stretch="None"/>
    </ComboBoxItem>
    <ComboBoxItem local:AttHeader.Header="Top">
        <Image Source="../images/ViewTypeTop.png" Stretch="None"/>
    </ComboBoxItem>
</ComboBox>

在创建这些ComboBoxItem时,即使设置这些ComboBoxItem的附加属性的值也不会影响其中的TextBlock。

我假设绑定有效,因为我可以为依赖项属性设置默认值,每个ComboBoxItem将始终在其图像旁边显示该值。

我在SetHeader中设置了一个断点,并且在构造这些ComboBoxItem时确实调用它。

我做错了什么或者绑定是否有一些我不知道的限制?

2 个答案:

答案 0 :(得分:2)

你的绑定不正确,TextBlock现在是ComboBoxItem的子节点 尝试绑定到:

 <Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="ComboBoxItem">
            <StackPanel Orientation="Horizontal">
                <ContentPresenter />
                <TextBlock Name="HeaderHost" 
                           Text="{Binding Path=local:AttHeader.Header,
                                  RelativeSource={RelativeSource Mode=FindAncestor
                                  ,AncestorType=ComboBoxItem}}" />
            </StackPanel>
        </ControlTemplate>
    </Setter.Value>
 </Setter>

答案 1 :(得分:0)

我仍然无法使用标头绑定来处理该实现,但这是一个非常简单方便的解决方法:使用HeaderedContentControls而不是ComboBoxItems,并指示您的ComboBox通过实现以下方式水平定位标题式:

<Style TargetType="HeaderedContentControl">
    <Setter Property="OverridesDefaultStyle" Value="True"/>
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="HeaderedContentControl">
                <StackPanel Orientation="Horizontal">
                    <ContentPresenter />
                    <ContentPresenter ContentSource="Header" />
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>