Вопрос

Как я могу привязаться к UserControlсобственность изнутри ResourceDictionary?Я хочу, чтобы объект, который я объявляю в своих ресурсах, имел то же самое DataContext как UserControl он содержится в:

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Some.Namespace"
    DataContext="{Binding Path=ViewModel, RelativeSource={RelativeSource Self}}">
    <UserControl.Resources>
        <local:SomeClass
            x:Key="SomeClass"
            DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
    </UserControl.Resources>
</UserControl>

Во время выполнения я получаю ошибку:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='UserControl', AncestorLevel='1''. BindingExpression:Path=DataContext; DataItem=null; target element is 'SomeClass' (Name=''); target property is 'DataContext' (type 'Object')

Это было полезно?

Решение

Мой обходной путь заключался в том, чтобы установить DataContext ресурса в выделенном коде.

.xaml

<local:SomeType x:Key="SomeKey" SomeProperty="{Binding ... }" />

.xaml.cs

public SomeControl()
{
    InitializeComponent();
    ((SomeType)this.Resources["SomeKey"]).DataContext = this;
}

Другие советы

При использовании FindAncestor целевой элемент должен быть потомком (логическим или визуальным) источника.Ваш объект не отображается ни в визуальном, ни в логическом дереве, он просто находится в ресурсах.Таким образом, вы не можете использовать RelativeSource с FindAncestor для своего объекта.

Однако вы можете использовать ElementName в своей привязке.Что-то вроде этого должно работать:

<UserControl x:Name="userControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Some.Namespace"
    DataContext="{Binding Path=ViewModel, RelativeSource={RelativeSource Self}}">
    <UserControl.Resources>
        <local:SomeClass
            x:Key="SomeClass"
            DataContext="{Binding Path=DataContext, ElementName=userControl}" />
    </UserControl.Resources>
</UserControl>

Набор х: общий="False", это будет клонировать ресурс при каждом использовании и делать его дочерним элементом вашего элемента, позволяя использовать привязки.

<local:SomeClass
            x:Key="SomeClass"
            x:Shared="False"
            DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />

Я думаю, что вы ищете просто {Binding}, который привязывается к унаследованному DataContext.Вот пример, хотя и немного странный, показывающий, как можно получить цвет посредством привязки к DataContext:

<Window x:Class="AncestorBinding.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <SolidColorBrush x:Key="MyBrush" Color="Blue" />
    </Window.Resources>
    <StackPanel>
        <Button DataContext="{Binding Source={StaticResource MyBrush}}" Content="My Button">
            <Button.Resources>
                <Style TargetType="{x:Type Button}">
                    <Setter Property="Background" Value="{Binding}" />
                </Style>
            </Button.Resources>
        </Button>
    </StackPanel>
</Window>

Я бы создал прикрепленное поведение (ContextualizeResourceBehavior) для пользовательского элемента управления и указал ключ ресурса для этого прикрепленного поведения.Поведение будет искать ресурс (не уверен, что вы сможете сделать это при подключении, в противном случае вам нужно будет подключить событие Loaded) и передавать контекст данных.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top