如何进一步将此 WPF 示例与 MVC、MVP 或 MVVM 解耦?
我已通过以下方式解耦此 WPF 应用程序中的事件。
继续脱钩的最佳方式是什么?
Shell.xaml:
<Button x:Name="btnProcess"
Content="Process"
Margin="10"/>
Bootstrapper.cs:
public void Run()
{
Shell shell = new Shell(new Customer());
shell.Show();
}
Shell.xaml.cs:
public Shell(IPerson person)
{
InitializeComponent();
btnProcess.Click +=new RoutedEventHandler(person.Process);
}
Customer.cs:
public class Customer : IPerson
{
public void Process(object sender, RoutedEventArgs e)
{
Button theButton = (Button)sender;
theButton.Content = "Customer processed.";
}
}
以上代码成功将视图 Shell
与模型 Customer:IPerson
分离,以便我可以交换处理“已处理”的模型 Employee:IPerson
等以它自己的方式。 这是第一个进球。
但现在:
- 如何将
Processed
方法与专门与 Button 对话分离,以便它也可以与在视图中触发事件的 MenuItem 或 ListView 对话这样它甚至不必是调用它的元素,例如单元测试类? - 除了发送者(按钮)之外,如何更改视图的其他元素,例如,如何更改 Shell 中的状态栏? 我看到两种方法:
- 我可以构建一个包含所有视图的容器,并在创建时将容器注入到客户中,然后客户可以在容器中查看并以任何想要的方式操作调用视图(尽管我会必须以某种方式将发送事件的视图与容器中的视图匹配为同一视图)
- 在触发事件时,我可以以某种方式使用 eventargs 将整个视图(Window 对象)发送到模型,尽管模型需要某种方式(通过界面)了解哪些类型的区域可在运行时进行操作
- 您将如何继续该应用程序朝着更加解耦的设计方向发展?
- 这实际上是什么模式,例如 MVC、MVP、MVVM? 我只看到一个视图(Shell)和一个模型(客户)。
- 演示者如何融入其中?
- ViewModel 如何融入其中?
- 控制器如何融入其中?
I've decoupled events in this WPF application in the following way.
What is the best way to continue decoupling?
Shell.xaml:
<Button x:Name="btnProcess"
Content="Process"
Margin="10"/>
Bootstrapper.cs:
public void Run()
{
Shell shell = new Shell(new Customer());
shell.Show();
}
Shell.xaml.cs:
public Shell(IPerson person)
{
InitializeComponent();
btnProcess.Click +=new RoutedEventHandler(person.Process);
}
Customer.cs:
public class Customer : IPerson
{
public void Process(object sender, RoutedEventArgs e)
{
Button theButton = (Button)sender;
theButton.Content = "Customer processed.";
}
}
The above code successfully decouples the view Shell
from the model Customer:IPerson
so that I can swap in e.g. a model Employee:IPerson
etc. which handles "Processed" in its own way. That was the first goal.
But now:
- how do I decouple the
Processed
method from talking specifically to a Button, so that it could also talk to a MenuItem or a ListView which fires the event in the view and so that it doesn't even have to be an element at all that calls it, e.g. a unit test class? - how do I alter other elements of the view other than the sender (Button), e.g. how would I alter the status bar in Shell? I see two ways:
- I could either build a container which holds all views and inject the container in the Customer upon creation, then the customer can look in the container and manipulate the calling view anyway it wants (although I would have to somehow match the view that sent the event and the view in the container as the same one)
- I could somehow send the whole view (Window object) to the Model with the eventargs when firing the event, although the Model would need some way of knowing (via interface) what kinds of regions were available to manipulate at runtime
- How would you continue this application in the direction of a more decoupled design?
- What pattern is this actually, e.g. MVC, MVP, MVVM? I only see a view (Shell) and a Model (Customer).
- How would a Presenter fit in?
- How would a ViewModel fit in?
- How would a Controller fit in?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正如陈建议的那样,我会研究命令模式: 路由命令
我从中学到了很多东西的工作示例可以在 Jaime Rodriquez 的博客上找到:南岭
As Chen suggests, i'd look into the Command pattern: Routed commands
A working example from which i learned a lot can be found on Jaime Rodriquez his blog: Southridge
如何将 Processed 方法与专门与 Button 对话分离
命令。 将命令放入 IPerson 界面并从 Shell 的 xaml 调用该命令。
如何更改视图的其他元素
属性和绑定。 如果您有一个显示状态(已处理/未处理)的属性,那么您可以使用绑定直接在 xaml 中显示该属性。
您将如何继续
我会通过在 Shell 和 IPerson 之间创建一个 ViewModel 来进一步沿着 MVVM 路径前进。 ViewModel 被设计为具有 1) 绑定所需的属性,以及 2) 需要执行的任何命令。 ViewModel 旨在为 UI 提供模型所需的内容。
这是什么图案
现在? 没有什么。 我只看到两个对象:视图和模型。 您没有 Presenter、Controller 或 ViewModel。
对于 WPF,我更喜欢 ViewModel。 有关 MVVM 的更多信息,请参阅此问题。
how do I decouple the Processed method from talking specifically to a Button
Commands. Put a command in the IPerson interface and call that command from the Shell's xaml.
how do I alter other elements of the view
Properties and Binding. If you have a property showing the state (processed/not processed) then you can use binding to display that property directly in the xaml.
How would you continue
I'd head more down the MVVM path by creating a ViewModel between the Shell and the IPerson. The ViewModel is designed to have 1) The properties needed for bindings, and 2) any Commands that need executing. The ViewModel is designed to provide the UI with what it needs from the Model.
What pattern is this
Currently? Nothing. I see only two objects, the View and the Model. You don't have a Presenter, Controller or ViewModel.
For WPF I prefer ViewModel. See this question for more info on MVVM.
我建议您使用命令而不是经典事件来实现事件处理。
在 WPF 中这非常容易,因为命令模式已经实现,您可以告诉所有 UI 输入(按钮、菜单项...)它们的命令是 [命令名称] 并在一个位置处理所有这些输入。
I suggest you to implement your event handling using commands instead of classic events.
Its very easy in WPF because the command pattern is already implemented, and you can tell all of your UI inputs (button, menu item...) that their command is [name of your command] and handle all of them in one place.
卡梅伦·麦克法兰(Cameron MacFarland)在这里做得很好,但我可以补充一点。
当遵循 MV-VM 时,盒子里用于解耦的工具是数据绑定、命令、附加行为和接口。 数据绑定应该是不言而喻的。 您已经对命令有了很好的描述,但我建议您避免使用 RoutedCommand 并坚持使用 ICommand 实现。 附加行为是附加的 DependencyProperty,它们订阅它们附加到的元素上的事件,在这种情况下将用于将事件处理中继到 ViewModel。 接口为您提供了最大的灵活性,但您必须弄清楚如何将接口传递给 ViewModel。 现在了解所有这些内容的最佳方法是 Google 并查看现有的 MV-VM 框架。 以下是框架列表:
Prism/Composite WPF (http://www.codeplex.com/CompositeWPF< /a>)。 这个来自 Microsoft Patterns & 实践组。 这里有很多好东西,但是您可以从这里学到的上述三件事的示例之一是如何使用 ICommand。 Prism 包含一个 DelegateCommand,它实现 ICommand 并简化在 MV-VM 中使用来自 ViewModel 的命令。
Caliburn (http://www.codeplex.com/caliburn)。 最近发布的,您可以从中学到的关键知识之一是如何使用附加行为,该库将其用于“操作”。
Onyx (http://www.codeplex.com/wpfonyx)。 免责声明:我是本文的作者。 尽管当前的 alpha 源代码已经可用,但该版本尚未发布。 这为如何向 ViewModel 提供接口的问题提供了一种新颖的解决方案。
Cameron MacFarland did a good job here, but I can add a little.
When following M-V-VM, the tools in your box for decoupling are data binding, commands, attached behaviors and interfaces. Data binding should be self evident. You've already gotten a good description of commands, but I'd suggest you avoid RoutedCommand and stick with an ICommand implementation. Attached behaviors are attached DependencyProperty's that subscribe to events on the element they are attached to, and in this scenario would be used to relay event handling to the ViewModel. Interfaces give you the greatest flexibility, but you have to work out how to pass the interface to the ViewModel. The best way to learn all of this right now is to Google and to look at existing M-V-VM frameworks. Here's a list of frameworks:
Prism/Composite WPF (http://www.codeplex.com/CompositeWPF). This one comes from the Microsoft Patterns & Practices group. Lots of good stuff here, but one of the examples of the three things above that you can learn from here is how to use ICommand. Prism includes a DelegateCommand that implements ICommand and simplifies using commands from a ViewModel in M-V-VM.
Caliburn (http://www.codeplex.com/caliburn). Recently released, one of the key things you can learn from this one is how to use attached behaviors, which this library uses for it's "Actions".
Onyx (http://www.codeplex.com/wpfonyx). Disclaimer: I'm the author of this one. This one hasn't been released yet, though the current alpha source is available. This one provides a novel solution to the problem of how to provide interfaces to your ViewModel.