2012-10-03 72 views
2

我试图建立一个系统,它允许我将一个字符串值附加到ComboBoxItem并将其显示在ComboBoxItem的内容旁边,而不必在每个人的内部显式嵌套一个StackPanel ComboBoxItem或使用自定义控件。控制模板的命令绑定与附加属性

所以我所做的就是创建一个名为“Header”的DependencyProperty并将其附加到ComboBoxItem,并且我重写了ComboBoxItem模板以包含具有TextBlock的堆栈面板,该TextBlock将其文本绑定到附加的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> 

即使设置这些ComboBoxItems创建时附加属性的值对其没有影响内的TextBlocks。

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

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

有没有我做错了或有没有限制我不知道的绑定?

回答

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> 
+0

啊,这做到了! – Nasai

+0

尝试使用snoop或观察输出窗口,您可以检测到绑定错误。 –

+0

从技术上讲,这是一个有效的绑定,并不会抛出任何错误,因为附加的属性并不关心你附加到哪个对象。 AFAIK,在其设置之前绑定到附加的字符串属性将返回空字符串,即使元数据中没有默认设置,也不会引发异常或错误。无论如何,我都这么认为。 – Nasai

0

我还没忘了头绑定与实施工作,但这里有一个超级简单方便的解决方法:使用HeaderedContentControls代替ComboBoxItems,并指示组合框通过实施以下样式水平定向头:

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