2

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

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

我遇到的问题是,在运行时出现在 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 时确实调用了它。

是我做错了什么还是我不知道绑定有一些限制?

4

2 回答 2

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>
于 2012-10-03T22:11:04.277 回答
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>
于 2012-10-03T21:39:20.023 回答