Элемент панели инструментов Привязка DataTemplate При поиске RelativeSource не удалось найти родительскую панель инструментов - PullRequest
0 голосов
/ 14 июля 2011

У меня есть панель инструментов, содержащая кнопки, некоторые кнопки имеют только изображение для содержимого, другие имеют только текст.Я пытаюсь связать свойство ширины изображения кнопки с пользовательским свойством в моем производном классе ToolBar.Иногда это работает, но в других случаях происходит сбой со следующей ошибкой:

System.Windows.Data Ошибка: 4: Не удается найти источник для привязки со ссылкой «RelativeSource FindAncestor, AncestorType =« NuiWpfCore.Controls.ToolBar », AncestorLevel = '1' '.BindingExpression: Path = IconSize;DataItem = NULL;целевым элементом является '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 голосов
/ 14 июля 2011

DataTemplate выглядит так, как будто он определен в объявлении DataTemplateSelector, которое не является частью Visual Tree, и поэтому не сможет перемещаться вверх оттуда, если привязка была оценена в этом месте. Где на самом деле применяется шаблон?

0 голосов
/ 14 июля 2011

Рассматривали ли вы сделать 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);
}

Тогда вы можете просто получить доступ к IconSize, как

<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}}"/>

Сначала вы должны установить его на панели инструментов, и любой другой элемент в дереве может получить доступ к этому свойству.

Извините, я не уверен на 100%, чтобы быть правильным. Но общая идея Value Inheritance - хороший способ решить эту проблему.

...