C# 列出/详细说明不同窗口是否可以同步并数据绑定到同一集合?

C# 列出/详细说明不同窗口是否可以同步并数据绑定到同一集合?,c#,.net,wpf,data-binding,windowing,C#,.net,Wpf,Data Binding,Windowing,我有一个绑定到列表的列表框——这非常有效 我想让我的用户双击一个列表框项目并打开一个新窗口,该窗口将显示该记录的“详细信息”视图。我希望此新窗口与原始窗口上的列表框数据绑定到同一集合。因为,该窗口有一个计时器,用于轮询webserivce以获取更新的数据,所以我希望子窗口(详细信息窗口)也在主列表更新时更新 这容易做到吗?举个例子会很好,但是任何帮助都是非常感谢的 您可以直接共享数据(即将SelectedItem引用传递给子窗口),但这无助于跨多个窗口管理行为和状态。如果它是一个只读视图,那么问

我有一个绑定到
列表的列表框
——这非常有效

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


这容易做到吗?举个例子会很好,但是任何帮助都是非常感谢的

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

这是使用模型视图的好处的一个很好的例子-?图案通常是WPF的首选模式,因为WPF是为完全分离表示而设计的。然而,在这种情况下,您可能需要更接近(模型-视图-控制器)的东西,因为您确实想要协调不同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注入windows(包括main),以便于绑定。它还将绑定到主窗口上的事件,启动子窗口,并可能绑定到子窗口事件以正确管理它们(例如,每个子记录一个窗口,在主窗口关闭时关闭子窗口,等等)

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

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
};
公共接口IControllerChild
{
公开无效显示();
公共bool Activate();
公共空间关闭();
//在此处添加其他行为
}
公共类详细信息窗口:窗口,IControllerChild
{
//在这里实现其他行为
}
公共类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);}
公共布尔值显示{get;private set;}
公共IList操作日志{get;private set;}
//在此处模拟并记录其他行为
}
公共枚举MockControllerAction
{ 
显示
激活,
接近,
//在此处添加其他行为
};

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

这是使用模型视图的好处的一个很好的例子-?图案通常是WPF的首选模式,因为WPF是为完全分离表示而设计的。然而,在这种情况下,您可能需要更接近(模型-视图-控制器)的东西,因为您确实想要协调不同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注入windows(包括main),以便于绑定。它还将绑定到主窗口上的事件,启动子窗口,并可能绑定到子窗口事件以正确管理它们(例如,每个子记录一个窗口,在主窗口关闭时关闭子窗口,等等)

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

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
};
公共接口IControllerChild
{
公开无效显示();
公共bool Activate();
公共空间关闭();
//在此处添加其他行为
}
公共类详细信息窗口:窗口,IControllerChild
{
//在这里实现其他行为
}
公共类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);}
公共布尔值显示{get;private set;}
公共IList操作日志{get;private set;}
//在此处模拟并记录其他行为
}
公众的