Что именно делает «RelativeSource FindAncestor» WPF Data Binding? - PullRequest
21 голосов
/ 28 октября 2009

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

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

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

не работает? Я получаю сообщение об ошибке:

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

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

Ответы [ 3 ]

18 голосов
/ 28 октября 2009

Лучший способ - присвоить имя UserControl

Создайте свойство зависимостей MyProperty в UserControl с двухсторонней привязкой и свяжите его в главном окне, чем привязать в UserControl следующим образом

<UserControl x:Name = "myControl">
     <Label Content={Binding ElementName= myControl, Path=MyProperty}/>
</UserControl>
4 голосов
/ 16 ноября 2011

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

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

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

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

namespace MyWPFApplication.Views {
   public class DataContextWrapper : Grid
   {

   }
}

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

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

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

1 голос
/ 20 апреля 2011

Думаю, вам следует установить SET Mode = "OneWayToSource", например:

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