2016-06-24 3 views
1

У меня есть диалог WPF, и я пытаюсь получить доступ к свойству в ViewModel владельца.WPF-Dialog Relative Source Binding (MVVM)

Я попытался следующие, но он связывается с ViewModel диалога:

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

Я также попытался:

<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, 
     AncestorType={x:Type Window}}, Path=Owner.DataContext.Property}"/> 

Но это дает тот же результат.

Код пользователя для создания диалога является:

 var dialog = new Dialog(DialogViewModel) 
     { 
      Owner = Window.GetWindow(this) 
     }; 

Я видел несколько вопросов в StackOverflow, но никто не похоже на работу.

Любые идеи? И возможно ли иметь относительный источник в диалоговом окне?

+0

Я бы ожидал, что 'Owner.DataContext.Property' будет работать, как в вашем втором примере, но добавив' .Property'. –

+0

Это была опечатка. –

+0

Извините, я забыл об этом, но он дает тот же результат. –

ответ

1

Это работает для меня, если я явно установить владельца на подокна:

<ComboBox 
    ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=Owner.DataContext.Property}"/> 

Однако: Там важный нюанс, который я думаю, что, возможно, возможно, будет вопрос вы испытываете: Если подокно является частным членом родителя, и я установил владельца непосредственно перед показом subwindow, он пытается разрешить привязку перед отображением subwindow. Владелец в это время имеет значение null, и он не повторяет попытку, когда Владелец будет установлен позже.

Однако, если я создаю новый экземпляр subwindow в методе, где я его показываю, задайте Owner, а затем вызовите ShowDialog() на нем, привязка будет правильно разрешена с ненулевым значением для Owner. Я уверен, что причина в том, что владелец не является DependencyProperty, а также не вызывает PropertyChanged, поэтому ничего не происходит, чтобы вызвать какие-либо обновления в ответ на изменение владельца. Если я установлю его на новый экземпляр окна, в то время как поток пользовательского интерфейса блокирует обработчик событий, то новый экземпляр окна не обойдется без каких-либо действий с привязками до тех пор, пока его владелец не будет установлен. Но если я создал его раньше, а затем разрешил поток пользовательского интерфейса, то уже слишком поздно.

Это не то, с чем вы хотите общаться.

Моя рекомендация:

Дайте SubWindow свойство, как так:

#region OwnerDataContext Property 
public Object OwnerDataContext 
{ 
    get { return (Object)GetValue(OwnerDataContextProperty); } 
    set { SetValue(OwnerDataContextProperty, value); } 
} 

public static readonly DependencyProperty OwnerDataContextProperty = 
    DependencyProperty.Register("OwnerDataContext", typeof(Object), typeof(SubWindow), 
     new PropertyMetadata(null)); 
#endregion OwnerDataContext Property 

Затем, когда вы показываете подокно ...

var dialog = new Dialog(DialogViewModel) 
{ 
    Owner = Window.GetWindow(this), 
    OwnerDataContext = DataContext 
}; 

Будучи DependencyProperty, привязок будет взаимодействовать с это правильно. Окно владельца может установить его по желанию, и вы можете привязать его. Способ привязки работает, он утиный, поэтому совершенно не имеет значения для привязки, что OwnerDataContext имеет объявленный тип объекта. Все равно это отражение.

<ComboBox 
    ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=OwnerDataContext.Property}"/> 

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

+0

Возможно, это вне контекста, но методы GetValue() и SetValue() находятся в некоторой библиотеке или это пользовательская реализация? Спасибо –

+0

@ J.Pichardo Они унаследованы от DependencyObject IIRC. Свойства зависимостей являются фундаментальной частью WPF. Это вам неприятности? –