Список/Подробности Можно ли синхронизировать и привязать данные к одной и той же коллекции в разных Windows?

У меня есть список, привязанный к List<T> — он отлично работает.

Я хотел бы, чтобы мои пользователи дважды щелкнули элемент списка и открыли новое окно, в котором будет отображаться «подробное» представление для этой записи. Я бы хотел, чтобы это новое окно было привязано к той же коллекции, что и список в исходном окне. Поскольку в этом окне есть таймер, который опрашивает веб-сервис на предмет обновленных данных, я бы хотел, чтобы дочернее окно (детальное окно) также обновлялось при обновлении основного списка.

Легко ли это сделать? Пример был бы замечательным, но любая помощь приветствуется!


person Nate    schedule 12.10.2009    source источник


Ответы (1)


Вы можете поделиться данными напрямую (т.е. передать ссылку 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
comment
Спасибо, что нашли время предоставить такой подробный ответ. Мне придется изучить это и немного переварить; это кажется излишним для того, что я хочу, но я понимаю, что это лучшая практика. - person Nate; 13.10.2009
comment
Однако, приняв лучший ответ, в моем случае я смог просто передать ссылку на экземпляр туда и обратно, и это соответствовало моим потребностям. - person Nate; 20.10.2009