2009-10-28 5 views
22

В настоящее время я работаю в пользовательском элементе WPF (корневой элемент моего файла XAML - «UserControl»), который, как мне известно, размещается внутри окна. Как я могу получить доступ к свойству окна, используя привязку данных?Что такое WPF Data Binding «RelativeSource FindAncestor»?

Кто-нибудь знает, почему просто

<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" Path="..." /> 

не работает? Сообщение об ошибке, которое я получаю:

System.Windows.Data Предупреждение: 4: Не удается найти источник для привязки со ссылкой «RelativeSource FindAncestor, AncestorType =« System.Windows.Window », AncestorLevel = '1' '.

Редактировать: В результате я использовал вариант подхода ArsenMkrt, поэтому принял его ответ. Тем не менее, мне все еще интересно узнать, почему FindAncestor не «просто работает».

+2

Вы сказали, что изменили свой ответ, можете ли вы опубликовать то, что вы на самом деле сделали? – Miles

+0

Обратите внимание, что я искал решение этой проблемы в контексте шаблона MVVM. Свойство Window, которое я хотел связать, на самом деле было свойством ViewModel Window. – user200783

+1

ArsenMkrt предложил создать свойство в UserControl и привязать к нему, а затем, в свою очередь (в XAML) привязать это свойство к желаемому свойству окна. Однако с шаблоном MVVM UserControl никогда не появлялся в XAML, поэтому вторая часть была невозможна. – user200783

ответ

15

Самый лучший способ, чтобы дать имя UserControl

Создание зависимостей свойств MyProperty в UserControl с два способа связывания и связать его в главном окне, чем связывать в UserControl как этот

<UserControl x:Name = "myControl"> 
    <Label Content={Binding ElementName= myControl, Path=MyProperty}/> 
</UserControl> 
+0

Но я хочу привязать свойство к содержащемуся окну (определенному в другом файле XAML), а не к UserControl. – user200783

+0

Чем лучше иметь свойство в usercontrol и связать это свойство с свойством окна –

+2

Можете ли вы создать свойство зависимостей в UserControl? вы не добавляете usercontrol в окно?

0

I Think вы должны установить режим = «OneWayToSource» Как это:

<TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor ,AncestorType={x:Type Grid}},Path=BackGround , Mode=OneWayToSource , UpdateSourceTrigger = PropertyChanged}" /> 
4

Если вы пытаетесь «убежать» от ItemsControlили 10, чтобы добраться до Window, вы можете обнаружить, что AncestorType x:Type Window не работает. Или, по крайней мере, не кажется ...

Если это так, вы, вероятно, используете Blend или Visual Studio и ожидаете, что данные будут видны во время разработки, что не будет, потому что VS + Blend оба создайте свои собственные экземпляры, которые на самом деле не являются Windows. Он будет работать во время выполнения просто отлично, но не во время режима разработки.

Там есть пара вещей, которые вы можете сделать:

  • Wrap в UserControl

  • Вот альтернативное решение, которое я придумал. У него есть одно преимущество в том, что вы не ссылаетесь непосредственно на UserControl или Window, поэтому, если вы измените родительский контейнер, ваш код не сломается.

    <Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:views="clr-namespace:MyWPFApplication.Views" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     
    x:Class="MyWPFApplication.Views.UPCLabelPrinterWindow" 
    mc:Ignorable="d" 
    x:Name="LayoutRoot" 
    Title="UPCLabelPrinterWindow"> 
    
    <views:DataContextWrapper> 
        <DockPanel> 
         ... 
        </DockPanel> 
    </views:DataContextWrapper> 
    

Где DataContextWrapper просто Сетка

namespace MyWPFApplication.Views { 
    public class DataContextWrapper : Grid 
    { 

    } 
} 

Затем, когда вы связываете вы это делаете:

<TextBlock Text="{Binding="{Binding DataContext.SomeText, 
    RelativeSource={RelativeSource AncestorType={x:Type views:DataContextWrapper}, 
    Mode=FindAncestor}}" /> 

Примечание: если вы хотите связать с собственность ON Window сама по себе сложнее и вы, вероятно, должны связываться через свойство зависимости или что-то в этом роде. Но если вы используете MVVM, то это одно из решений, которое я нашел.

+0

В моем случае 'AncestorType = {x: Type Window}' было очень полезно, потому что 'AncestorType = UserControl' каким-то образом не указывал на мое окно - все это нормально. – LuckyLikey