1

我有一个绑定到的列表框List<T>——这很好用。

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

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

4

1 回答 1

7

您可以直接共享数据(即将 SelectedItem 引用传递给子窗口),但这无助于您管理跨多个窗口的行为和状态。如果它是只读视图,则问题不大,但是如果正在更改数据,它很快就会变得非常有问题。

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

我会推荐一种混合方法,我们称它为“MVVMC”只是为了让首字母缩写词更长更尴尬。实现一个完全与 UI 无关的 ViewModel,只公开数据和与数据相关的状态/行为——可能主要是 CRUD 类型的东西。然后实现一个特定于你的 UI 设计的控制器,它消耗和公开(通过委托或组合) 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,然后反转控制,以便控制器可以管理多窗口 UI。所以这里的控制器会将 ViewModel 作为 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
};
于 2009-10-12T16:43:07.897 回答