2017-01-30 3 views
0

Я пытаюсь очистить способ использования DataContexts с моим UserControls, и в настоящее время я сталкиваюсь с проблемой, когда мне нужно привязать DataControl к элементу TabItem к DataContext родительского окна.Связывание TabItem с родительским окном

Вот набросок того, что мое окно выглядит следующим образом:

enter image description here

Как вы можете видеть, это окно владеет TabControl, который содержит TabItems, которые динамически добавляются через «Вкладки» ItemSource. Связывание данных в этой точке работает, потому что «Tabs» заполняется вкладкой 1.

Вкладка 1 содержит UserControl, которая нуждается в доступе к нескольким свойствам строки в DiagnosticsViewModel, но когда я запускаю приложение, окно «Выход» указывает, что все привязки провалился. Например:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Window', AncestorLevel='1''. BindingExpression:Path=Property1; DataItem=null; target element is 'Tab1UserControl' (Name=''); target property is 'UCName' (type 'String')

Часть XAML для UserControl в Tab 1 выглядит примерно так:

<Grid> 
    <uc:Tab1UserControl UCName="{Binding Property1, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" /> 
</Grid> 

где UCName является строка DependencyProperty.

Если я рассказываю WPF, что я хочу искать дерево и привязываться к DataContext для ближайшего окна, а в DataContext моего окна установлено значение DiagnosticsViewModel, почему он не использует его для DataContext UserControl? Я не установил DataContext = this в свой UserControl, поскольку я делал это неправильно много раз в прошлом, ожидая, что мой UserControl сможет наследовать DataContext от его родителя.

Я хотел бы посмотреть, может ли Snoop пролить свет на мою проблему, но этот графический интерфейс отображается в приложении MFC, и Snoop, похоже, не может подключиться к моему диалоговому окну WPF.

ответ

1

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

Попробуйте использовать

<Grid> 
    <uc:Tab1UserControl UCName="{Binding Path=DataContext.Property1, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" /> 
</Grid> 

в коде для пользовательского элемента управления и посмотреть, если это исправляет проблему.

(Как в стороне, идея пользовательского контроля, зная, что к окну, к которому он принадлежит, будет иметь datacontext с заданным свойством, кажется мне запахом кода, тем более, что точка пользовательских элементов управления заключается в том, re reableable - было бы лучше иметь свойство зависимостей в пользовательском элементе управления, а затем привязать его к соответствующему свойству, когда вы его используете. Это может быть связано только с отсутствием контекста.)

+0

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

+0

относительно вашего последнего комментария, UCName в моем UserControl * является * DependencyProperty, и я делаю это так, чтобы потребитель UserControl мог установить одно из своих значений первоначального свойства. Это похоже на более приемлемый подход? – Dave

+0

Извините, я прочитал привязку как находящуюся в определении самого пользовательского элемента управления, а не там, где он использовался вкладкой по какой-то причине. То, как вы это делаете, - вполне приемлемый подход, и я не знаю, как я это неправильно понял! – Astrid