已经有一段时间了 - 所以我不会提供太多代码块 - 但听起来您可能想要应用 MVC,或者它的表亲 MVP 或 MVVM。不要太担心它们代表什么,但一般来说,它们会尝试定义 View [您的窗口]、Data [您的网络层结果] 和 Business [您的网络层] 之间的关系。
在你的情况下,我会推荐 MVVM。如果你谷歌它,你应该能够找到关于设计模式和应用它的方法的大量信息。再次,不要对理论大惊小怪。仅供参考。
接下来,来点肉,
从概念上讲,您希望在“视图”中表示“数据”。不用担心视图,让我们先封装你的数据。
// name is a little too general, so just rename it to something
// specific in your source.
public class NetworkViewModel
{
// enumerate your data here
public int Trouble { get; set; }
public int Tribbles { get; set; }
...
}
您的视野就是您的窗口。让您的视图实例化此“视图模型”的实例
public class MyNetworkMonitor
{
...
// advanced: if you were injecting this - say from another source
// or intended to replace the instance during runtime, there are
// ways to deal with that. for now, we presume one instance for
// application lifetime.
public NetworkViewModel ViewModel { get; set; }
public MyNetworkMonitor ()
{
ViewModel = new NetworkViewModel ();
}
...
}
在您的 Xaml 中,绑定到属性
// Xaml omitted, a limit to my memory :P
// but just regular binding to say ViewModel.Trouble
好的。因此,如果您的视图模型具有初始值,它将显示给绑定控件。不幸的是,如果视图模型属性更新,则无法告诉绑定控件该值已更改。呃,当然除非你实现了 Wpf 绑定寻找的通用接口,
public class NetworkViewModel : INotifyPropertyChanged
{
// defined by interface
public event PropertyChangedEventHandler PropertyChanged;
private int _trouble = 0;
public int Trouble
{
get { return _trouble; }
set
{
// 1. if value changes
if (_trouble != value)
{
_trouble = value;
// 2. inform whomever is listening!
if (PropertyChanged != null)
{
PropertyChanged (
this,
new PropertyChangedEventArgs ("Trouble"));
}
}
}
}
}
当然,您可以包装并做任何您想做的事情来简化语法,但前面是您在模型方面的基本实现。
如果您要处理窗口中的按钮按下并增加 ViewModel.Trouble,您将在绑定控件中看到实时更新。呵呵!
剩下的就是将您的业务层(即网络层)连接到您的 ViewModel。您可以通过多种方式做到这一点。您可以将视图模型的实例传递给网络层,也可以让视图模型直接响应网络层上的事件——这完全取决于您。
现在,如果您继续执行此操作,它将无法正常工作。对不起。现在,这不完全是我的错,你看 Wpf 不喜欢任何人修改它的数据。更具体地说,任何可能影响 Wpf 控件的内容必须在拥有该控件的 Gui 线程上调用。正如您可能猜到的,您用于修改视图模型的线程源自网络中断等。网络线程。恳求。 莫洛克人。 呸!
无论如何,我离题了。有一个相对无痛的方法来解决这个问题。当您检测到要报告的更改时,将更改分派到 Gui 线程。
someWpfControl.Dispatcher.Invoke (
DispatcherPriority.Normal,
new Action(
delegate()
{
ViewModel.Trouble = someNewValue;
});
但这有点没用,因为您的网络层不应该对 Wpf 有任何了解。那么在 ViewModel 中呢
...
// within property, after detecting change and
// testing for listeners
someWpfControl.Dispatcher.Invoke (
DispatcherPriority.Normal,
new Action(
delegate()
{
PropertyChanged (
this,
new PropertyChangedEventArgs ("Trouble"));
});
...
和以前一样,请随意将其包装在其他任何地方。就像在辅助方法中一样。顺便说一句,“someWpfControl”可以是窗口。所以你可以把它传递给ctor。我还强烈建议您使用 Google 替代“调用 Dispatcher”,因为这样做可能有更聪明的方法,不涉及控件引用、视图模型中的大量剪切和粘贴等。
只要 Gui 线程更新控件,你就可以为所欲为:)
另外,我的伴侣和 Wpf 门徒 Kent 的无耻插件,他对 Wpf 的了解比我自己多得多。 [http://kentb.blogspot.com/]
干杯:)