列表/详细信息不同的Windows可以同步并数据绑定到同一个集合吗?

Nat*_*ate 1 .net c# data-binding wpf windowing

我有一个绑定到的列表框List<T>- 这很有用.

我想让我的用户双击列表框项目并打开一个新窗口,该窗口将显示该记录的"详细信息"视图.我想将这个新窗口数据绑定到与原始窗口上的列表框相同的集合.因为,该窗口有一个计时器,它会轮询webserivce以获取更新的数据,我希望子列表(详细信息窗口)在主列表更新时也会更新.

这很容易吗?一个例子会很棒,但任何帮助都表示赞赏!

And*_*dyM 7

您可以直接共享数据(即将SelectedItem引用传递给子窗口),但这无助于您跨多个窗口管理行为和状态.如果它是一个只读的视图不是一个问题,但如果数据被更改,它很快就会出现问题.

这是使用模型 - 视图 - 的好处的一个很好的例子?图案.MVVM通常是WPF的首选模式,因为WPF是为完全分离呈现而设计的.但是,在这种情况下,您可能需要更接近MVC(模型 - 视图 - 控制器)的东西,因为您真的想要协调不同UI元素之间的行为和状态.

我会推荐一种混合方法,让它称之为"MVVMC"只是为了使缩写更长更尴尬.实现一个完全与UI无关的ViewModel,只暴露数据和数据相关的状态/行为 - 可能主要是CRUD类型的东西.然后实现一个特定于您的UI设计的Controller,它使用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 { ... }
}
Run Code Online (Sandbox Code Playgroud)

所以你真正做的是采用MVVM,然后反转控制,以便控制器可以管理多窗口UI.所以这里的控制器会将ViewModel注入到windows(包括main)中作为DataContext以便于绑定.它还会绑定到主窗口上的事件,启动子窗口,并可能绑定到子窗口事件以便正确管理它们(例如,每个子记录一个窗口,主关闭时关闭子窗口等).

我会更进一步,针对接口而不是Window实现控制器.这为您提供了一些重构的灵活性,但更重要的是允许您对模拟器进行单元测试.

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
};
Run Code Online (Sandbox Code Playgroud)