ToolBar项DataTemplate绑定RelativeSource搜索无法找到父ToolBar

时间:2011-07-14 18:06:09

标签: wpf data-binding toolbar relativesource findancestor

我有一个包含按钮的工具栏,一些按钮只有一个图像用于内容,其他按钮只有文本。我试图将Button Image的width属性绑定到派生的ToolBar类上的自定义属性。它有时会工作,但在其他时候失败并出现以下错误:

System.Windows.Data错误:4:无法找到与引用'RelativeSource FindAncestor绑定的源,AncestorType ='NuiWpfCore.Controls.ToolBar',AncestorLevel ='1''。 BindingExpression:路径= IconSize;的DataItem = NULL; target元素是'Image'(Name =''); target属性为'Width'(类型为'Double')

这是包含失败的元素绑定的xaml。 DataTemplate是从内联创建的DataTemplateSelector返回的:

<pres:ToolBar x:Class="NuiWpfCore.Controls.ToolBar"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:pres="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:core="clr-namespace:NuiWpfCore"
         xmlns:ctrls="clr-namespace:NuiWpfCore.Controls"
         xmlns:select="clr-namespace:NuiWpfCore.Selectors"
         xmlns:converters="clr-namespace:NuiWpfCore.Converters"
         xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase">

    <ToolBar.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/NuiWpfCore;component/Controls/MenuBarTemplate.xaml" />
            </ResourceDictionary.MergedDictionaries>
            <converters:ListPairToStringConverter x:Key="ListPairToStringConverter" />
            <converters:IconMetaDataToImageConverter x:Key="IconMetaDataToImageConverter" />
            <converters:IconMetaDataToImageConverterParameter x:Key="IconToImageConverterParameter"
                ConvertToImage="False" Width="16" Height="16" />
        </ResourceDictionary>
    </ToolBar.Resources>

    <ToolBar.ItemTemplateSelector>
        <select:ToolBarItemDataTemplateSelector>

            <!-- other DataTemplates omitted for brevity -->

            <select:ToolBarItemDataTemplateSelector.IconCommand>
                <DataTemplate DataType="{x:Type core:PropertyElement}">
                    <Button IsEnabled="{Binding Path=CanEdit}" Command="{Binding}">
                        <Button.Content>
                            <Image 
                                Width="{Binding Path=IconSize, 
                                    RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ctrls:ToolBar}} }" 
                                Height="{Binding Path=Width,
                                    RelativeSource={RelativeSource Self}}" 
                                Source="{Binding Path=MetaData, 
                                Converter={StaticResource IconMetaDataToImageConverter},
                                ConverterParameter={StaticResource IconToImageConverterParameter}}"/>
                        </Button.Content>
                    </Button>
                </DataTemplate>
            </select:ToolBarItemDataTemplateSelector.IconCommand>

            <!-- other DataTemplates omitted for brevity -->

        </select:ToolBarItemDataTemplateSelector>
    </ToolBar.ItemTemplateSelector>
</pres:ToolBar>

这是ToolBar类,其中包含绑定的Source属性。

public partial class ToolBar : System.Windows.Controls.ToolBar, Views.IView
{
    public ToolBar() : base()
    {
        InitializeComponent();
        IconSize = 32;
    }

    public int IconSize { get; set; }
}

此ToolBar类有时在ToolBarTray中使用,有时则不在,但在某些情况下,绑定搜索在两种情况下都会失败。

对于为什么会失败,有没有人有任何想法?

2 个答案:

答案 0 :(得分:0)

您是否考虑在工具栏上IconSize生成 public static readonly DependencyProperty IconSizeProperty = DependencyProperty.RegisterAttached( "IconSize", typeof(double), typeof(ToolBar ), new FrameworkPropertyMetadata(32, FrameworkPropertyMetadataOptions.Inherits)); public static double GetIconSize(DependencyObject target) { return (double)target.GetValue(IconSizeProperty); } public static void SetIconSize(DependencyObject target, double value) { target.SetValue(IconSizeProperty, value); }

<Button.Content>
                <Image 
                    Width="{Binding RelativeSource={RelativeSource Self}, ctrls::ToolBar.IconSize}" 
                    Height="{Binding Path=Width,RelativeSource={RelativeSource Self}}" 
                    Source="{Binding Path=MetaData, 
                    Converter={StaticResource IconMetaDataToImageConverter},
                    ConverterParameter={StaticResource IconToImageConverterParameter}}"/>

然后您可以像

一样访问IconSize
{{1}}

首先,您应该在工具栏上设置它,树下的每个其他元素都可以访问此属性。

对不起我的头脑,不是100%保证是正确的。但总体思路 值继承是解决此问题的好方法。

答案 1 :(得分:0)

DataTemplate看起来像是在DataTemplateSelector声明中定义的,它不是Visual Tree的一部分,因此如果在该点中评估Binding,则无法从那里向上导航。实际应用的模板在哪里?