Вы можете поделиться данными напрямую (т.е. передать ссылку SelectedItem в дочернее окно), но это не поможет вам управлять поведением и состоянием нескольких окон. Если это представление только для чтения, это не проблема, но если данные изменяются, это очень быстро становится проблематичным.
Это хороший пример преимуществ использования Model-View-? шаблон. MVVM обычно является предпочтительным шаблоном для WPF, поскольку WPF разработан для полного разделения представления. Однако в таком случае вам может понадобиться что-то более близкое к MVC (Model-View-Controller), потому что вы действительно хотите координировать поведение и состояние между отдельными элементами пользовательского интерфейса.
Я бы порекомендовал гибридный подход, назовем его «MVVMC», просто чтобы сделать аббревиатуру еще длиннее и неуклюже. Реализуйте ViewModel, который полностью не зависит от пользовательского интерфейса и просто предоставляет данные и состояние/поведение, связанные с данными — вероятно, в основном это CRUD-тип. Затем реализуйте контроллер, специфичный для вашего дизайна пользовательского интерфейса, который использует и предоставляет (путем делегирования или композиции) ViewModel, но инкапсулирует. все поведение многооконного отображения - вещи, обеспечивающие одно окно для каждого элемента, распространяющие запросы на закрытие и т. д.
public class MyViewModel : INotifyPropertyChanged, INotifyCollectionChanged
{
public MyViewModel(DataModel dataModel) { ... }
}
public class MyController
{
public MyController(MainWindow mainWindow, ViewModel viewModel) { ... }
public ViewModel { get { return _viewModel; } }
public ICommand DisplayChild { ... }
}
Итак, на самом деле вы берете MVVM, а затем инвертируете управление, чтобы контроллер мог управлять многооконным пользовательским интерфейсом. Таким образом, контроллер здесь будет внедрять ViewModel в окна (включая основное) в качестве DataContext для легкой привязки. Он также будет привязываться к событиям в главном окне, запускать дочерние окна и, возможно, привязываться к событиям дочерних окон, чтобы правильно ими управлять (например, одно окно на дочернюю запись, закрывать дочерние элементы при закрытии основного и т. д.).
Я бы сделал еще один шаг вперед, реализовав контроллер для интерфейса вместо окна. Это дает вам некоторую гибкость в рефакторинге, но, что более важно, позволяет вам тестировать контроллер против моков.
public interface IControllerChild
{
public void Show();
public bool Activate();
public void Close();
// add other behaviors here
}
public class DetailWindow : Window, IControllerChild
{
// implement other behaviors here
}
public class MockControllerChild : IControllerChild
{
public void Show() { IsShowing = true; ActionLog.Add(MockControllerAction.Show); }
public void Activate() { IsShowing = false; ActionLog.Add(MockControllerAction.Activate); }
public void Close() { IsShowing = false; ActionLog.Add(MockControllerAction.Close); }
public bool IsShowing { get; private set; }
public IList<MockControllerAction> ActionLog { get; private set; }
// mock and record other behaviors here
}
public enum MockControllerAction
{
Show,
Activate,
Close,
// Add other behaviors here
};
person
AndyM
schedule
12.10.2009