最佳方法开发WPF应用程序

8
我想创建一个WPF应用程序,希望能够得到一些关于最合适的方法的建议。
我想创建一个RSS阅读器,当新的RSS条目添加时自动刷新。问题在于,我不想使用传统的控件(listbox / listview)来显示数据。我希望这些feed项目随机出现在屏幕上的面板中。这些面板由几个文本块组成,每个面板显示一个feed项目。
它的外观类似于这样:Concept 这引发了几个问题:
1. 完全从代码生成面板,还是使用自定义控件? 我会像上面描述的那样模拟一个类作为面板。该类手动向窗体添加所有控件,并将面板放置在窗体的随机位置。当添加新的RSS条目时,该类的一个实例被实例化,并将rss信息作为参数传递。
另一方面,创建一个UserControl可能更好。是否可以通过代码轻松创建此UserControl并将其传递给构造函数中的参数?
2. 当在线添加新的RSS条目时,我的数据/面板是否可以自动更新? 现在,我每(x)秒刷新一次所有内容,并针对面板集合检查是否需要创建新面板。如果是,则创建一个新面板并将其随机放置在窗体上。
有没有更好的方法?我可以使用本地ObservableCollection进行数据绑定,当集合发生变化时,它会自动更新控件(listbox等),那么在线源如RSS feed也可以这样做吗?
最理想的方式是,当添加新的RSS条目时,我的应用程序得到通知,下载最后一个条目并创建一个新面板(通过代码或UserControl)。
如果这很难实现,我将使用传统的刷新方法。
3. 我是否必须使用DependencyObject / DependencyProperty? 我知道DependencyObject和DependencyProperty为UserControls公开了一些强大的功能,但我不太知道如何使用它们。对于这种应用程序,它们是必需的吗?
4. 我是否必须使用WCF(Windows Communication Foundation)?
我对高级WPF内容(如高级数据绑定,DependencyObjects和UserControls)并不熟悉,但我很乐意学习!

你不必使用WCF,任何能够处理HTTP流量的类都可以。你也可以考虑创建自己的面板类,随机定位其子元素。这样,你只需要担心添加子元素(或将其绑定到可观察集合),其余的事情基本上会自动发生。 - Roman
1
这是一个好问题,但不适合在SO上提问。请花些时间阅读[faq],这样你就能写出优秀的问题并得到回答,而不是被关闭。 - John Saunders
4个回答

2
我建议首先研究使用MVVM设计模式,并使用MVVM框架。其次,您可以使用ItemsControl实现此效果,并将Canvas用作其ItemsPanel类型,然后可以使用自定义ItemTemplate来使用UserControl呈现每个数据对象。
用户控件将具有一个依赖属性,该属性是数据项,并且您将在item template声明中绑定它。
您可以拥有一个模型来模拟每个RSS条目(RSSEntry),并且也许还有一个RSSEntryViewModel,它会在画布上添加x和y坐标。
然后,您的屏幕视图模型将具有一个RSSViewModel的ObservableCollection,您可以添加/删除等操作,并且UI将自动更新。
如果您不想要服务层,那么只要您的视图模型通过抽象检索条目,将来很容易进行重构即可。

2
  1. 从代码完全生成面板,还是使用自定义控件?我通常尽可能在XAML中声明性地完成尽可能多的工作,分离逻辑和表现通常有助于应用程序的可扩展性和代码质量 - 但当然也有限制。 UserControl通常不应该在它们的构造函数中具有参数(并非不能具有参数,但必须具有无参数的构造函数,以便可以从XAML实例化类)。

  2. 当在线添加新的RSS条目时,我的数据/面板是否可以自动更新?必须有某些内容向WPF层发送更新通知,以便可以更新显示。在RSS应用程序的情况下,我想你将不得不定期手动扫描RSS频道以获取更新(RSS是一种拉技术),并在更新的情况下将该项添加到ObservableCollection中,它会为您发送适当的更新通知。

  3. 我必须使用DependencyObject / DependencyProperty吗?不,你可以使用INotifyPropertyChanged。 DependencyProperties通常用于作为绑定目标的属性(声明绑定的属性)或在将利用任何其他DP功能的属性中 - 值继承或动画。 INotifyPropertyChanged对于绑定到的属性足够了(在绑定表达式中命名的属性)。请注意,您可以使用NotifyPropertyWeaver自动生成INotifyPropertyChanged的通知 - 您只需创建OnPropetyChanged方法,然后编织器将在对象的任何属性更改时调用它!而且它甚至与Visual Studio完美集成。

  4. 我必须使用WCF(Windows Communication Foundation)吗?对于WCF,您必须有某些内容要进行通信 - 毕竟它是一个通信框架。你有吗?


1
  1. 你应该使用 WPF 的 ListView(或类似控件;不确定是哪个控件),并将其主题设置为与所需的“面板”想法相匹配。这是 WPF 的一个巨大优势。然后,您可以获得内置控件的所有好处,并获得任何外观。

  2. 绑定到 ObservableCollection;如何更新该可观察集合取决于您。我认为 RSS 没有“推送通知”的规范部分,因此通常使用轮询来完成这些操作。但最终并不重要;您代码的这一部分与 WPF 完全分离,只要它更新了 ObservableCollection,就可以了。

  3. 无论何种带有数据绑定的 WPF 应用程序,都通常需要 DependencyObject/DependencyProperty 或 INotifyPropertyChanged。值得学习它们,然后再学习一个为您抽象它们的框架。

  4. 不;WCF 与 WPF 没有任何关系。您可以使用任何技术与服务器通信。


0

1: 从代码完全生成面板,还是使用自定义控件?

创建两个视图模型类。一个类将模拟所有项目的视图,另一个表示单个项目的内容。前者将包含后者的可观察集合。

构建一个用户控件来显示每个项目。

容器视图将是一个ItemsControl,其ItemsSource绑定到其项目视图模型的集合,其ItemsPanel是一个Canvas,其ItemContainerStyleCanvas.TopCanvas.Left属性绑定到项目视图模型中的TopLeft属性。当向视图模型的集合添加新项目时,绑定将自动为其创建新面板。

项目视图模型将自动生成TopLeft的随机值。(您也可以在构造时要求它们从容器请求这些值。)

(如果“视图模型”这个术语对你来说毫无意义,那么你需要研究模型/视图/视图模型模式,也就是MVVM。)

2:当在线添加新的RSS条目时,我的数据/面板能否自动更新?

首先,你需要研究一下RSS聚合器的工作原理,因为你正在编写一个。这将向你解释从RSS源获取更新的机制。这个问题与获取更新后如何呈现更新的问题完全不同。

你的RSS聚合层将检查源,查找新项目,并在发现新项目时引发事件。你的UI层将处理聚合层引发的事件,并为每个接收到的新项目创建新的视图模型对象。

这种事件的使用完全将两个组件解耦。例如,你可以通过构建一个生成测试消息的模拟聚合器并让你的UI监听它来测试你的UI,而不是真正的聚合器。同样地,你可以测试你的聚合器而不必构建它——你只需构建一个注册其事件并将项目转储到控制台的侦听器。

3:我必须使用DependencyObject/DependencyProperty吗?

你可能不需要自己实现。

4:我必须使用WCF(Windows Communication Foundation)吗? 为什么不呢?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接