如何在这种特定的 WPF 情况下应用 MVVM 和命令?
我在使用 WPF 应用程序中的 MVVM 模式和命令时遇到问题。问题不在于 MVVM 模式,而在于我的 GUI 上发生的事情。我将解释这种情况:
我的应用程序可以对某些文件进行 DoStuff。我有一个带有函数 DoStuff(int limit)
的类。我的用户界面具有以下项目:
- 用于开始解析的
Button
DoStuffBtn
。 - 用于填写限制的
TextBox
LimitTxt
。 - 用于启用或禁用限制的
CheckBox
LimitChk
。
当您“取消选中”LimitChk
时,请选择 LimitTxt.Text = ""
和 LimitTxt.IsEnabled = false
。当您“检查”LimitChk
时,然后再次 LimitTxt.IsEnabled = false
,但文本仍为空,直到您填写一些内容。
我已经阅读了许多有关 WPF 中命令的教程和 MVVM,但我似乎无法将我的案例倒入那个模具中。我给出的例子实际上只是我的用户界面的一小部分,但我似乎也不能很好地做到这一点。
我不断遇到这样的问题:
LimitChk
需要两个Command
(启用和禁用)还是只需要一个(切换)?- 如果我将
int
绑定到LimitTxt
,如果我将其清空并禁用它,会发生什么情况? - 当按下
DoStuffBtn
时,仅使用DoStuff(Int32.Parse(LimitTxt.Text))
是一种干净的方法吗? - 如果我在
LimitChk
上使用两个命令,则ICommand
的CanExecute()
函数会发生什么情况来确定LimitChk
已启用?
所以主要问题是:我所描述的情况如何适合使用 WPF 中的命令的良好模式?
我查看过有关 WPF、命令和 MVVM 的一些链接:
- http: //www.devx.com/DevX/Article/37893/0/page/1
- http://msdn.microsoft.com/en-us/magazine/cc785480.aspx?pr=blog
- http: //jmorrill.hjtcentral.com/Home/tabid/428/EntryId/432/MVVM-for-Tarded-Folks-Like-Me-or-MVVM-and-What-it-Means-to-Me.aspx
- http://msdn.microsoft.com/en-us/magazine/dd419663 .aspx
到目前为止我的理解是我必须尽可能远离用户界面。甚至像 UI 这样的东西也会影响 UI。即取消选中 LimitChk
会禁用 LimitText
。尽管如此,我认为我应该在 UI 相关信息和操作以及实际上与必须完成的实际工作有关的内容之间保持区别。
I am having trouble with the MVVM pattern and Commands in my WPF app. The problem is not so much the MVVM pattern, but more the stuff that is going on on my GUI. I'll explain the situation:
My app can DoStuff to some files. I have a class with a function DoStuff(int limit)
. My user user interface has the following items:
- A
Button
DoStuffBtn
to start parsing. - A
TextBox
LimitTxt
to fill in a limit. - A
CheckBox
LimitChk
to enabled or disable the limit.
When you would "uncheck" LimitChk
, then LimitTxt.Text = ""
and LimitTxt.IsEnabled = false
. When you would "check" LimitChk
, then LimitTxt.IsEnabled = false
again, but the text remains empty until you fill something in.
I have read many tutorials on Commands in WPF and MVVM but I just can't seem to pour my case into that mold. The example I gave is actually just a small part of my UI, but I can't seem to do this nicely either.
I keep running into questions like:
- Do I need two
Commands
forLimitChk
(enable and disable) or just one (toggle)? - If I bind an
int
toLimitTxt
, what happens if I make it empty and disable it? - Is it a clean way to just use
DoStuff(Int32.Parse(LimitTxt.Text))
whenDoStuffBtn
is pressed? - If I use two commands on
LimitChk
, what happens with theCanExecute()
function ofICommand
that determines whetherLimitChk
is enabled?
So the main question is: How would the situation I described fit into a nice pattern using Commands in WPF?
Some links on WPF, Commands and MVVM i've looked at:
- http://www.devx.com/DevX/Article/37893/0/page/1
- http://msdn.microsoft.com/en-us/magazine/cc785480.aspx?pr=blog
- http://jmorrill.hjtcentral.com/Home/tabid/428/EntryId/432/MVVM-for-Tarded-Folks-Like-Me-or-MVVM-and-What-it-Means-to-Me.aspx
- http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
What I understand so far is that I have to keep as much as possible out of the UI. Even stuff like UI influencing the UI. I.e. unchecking LimitChk
disables LimitText
. Still, I think I should keep a difference between UI related information and actions and stuff that actually has to do with the actual work that has to be done.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您很困惑...这里不需要任何命令,您只需使用绑定即可。
你不需要。只需在 ViewModel 中创建一个
LimitEnabled
属性,并将CheckBox
绑定到它 (IsChecked="{Binding LimitEnabled}"
)禁用它没有任何影响。如果将
TextBox
设为空,则绑定将失败,因为空字符串无法转换为 int(至少使用默认转换器无法转换)你不需要。只需在 ViewModel 中创建一个
Limit
属性,并将TextBox
绑定到它即可。您可能需要将ExceptionValidationRule
添加到Binding
中,以便突出显示无效输入。该按钮不是必需的,当
TextBox
失去焦点时,解析将自动完成(如果您使用默认的UpdateSourceTrigger
)。如果您想自定义其解析方式,您可以创建一个自定义转换器以在绑定中使用。I think you're getting confused... you don't need any commands here, you can just use bindings.
You need none. Just create a
LimitEnabled
property in your ViewModel, and bind theCheckBox
to it (IsChecked="{Binding LimitEnabled}"
)Disabling it has no effect. If you make the
TextBox
empty, the binding will fail because an empty string can't be converted to an int (at least not with the default converter)You don't need to. Just create a
Limit
property in your ViewModel, and bind theTextBox
to it. You might want to add anExceptionValidationRule
to theBinding
so that it highlights invalid input.The button is not necessary, the parsing will be done automatically when the
TextBox
loses focus (if you use the defaultUpdateSourceTrigger
). If you want to customize the way it's parsed, you can create a custom converter to use in the binding.只是一些高层次的想法,省略诸如颜色和对齐属性、WrapPanels 等多余的东西。
您的 ViewModel 有几个属性:
您的 XAML 有 CheckBox 和 TextBox 定义,例如:
您需要初始化 ParseCommand,如下所示:
现在,让我们也填写 LimitTextIsEnabled 属性:
您的
parseFile
方法会将LimitValue
属性的值传递给执行实际解析的逻辑。我在此处将
LimitValue
属性声明为字符串,以避免显式转换器或其他验证代码使代码变得混乱。您可以选择以几种不同的方式处理“LimitValue is a valid int”验证/转换。当然,我还没有完全实现这一点,但我想概述一种模式,在这种模式中,您不使用命令来更新其他小部件的状态。相反,请将这些属性绑定到 ViewModel 中管理的属性。
Just some high level thoughts, leaving out superfluous stuff like Color and alignment attributes, WrapPanels, etc.
Your ViewModel has a a couple properties:
Your XAML has CheckBox and TextBox definitions something like:
You'll want to initialize ParseCommand something like this:
Now, let's fill in that LimitTextIsEnabled property too:
Your
parseFile
method would then pass the value of theLimitValue
property to the logic doing the actual parsing.I declared the
LimitValue
property as string here to avoid cluttering up the code with an explicit converter, or other validation code. You could choose to handle that "LimitValue is a valid int" verification/conversion in several different ways.Of course, I haven't implemented this in its entirety, but I wanted to outline a pattern where you are not using Commands to update the state of the other widgets. Instead, bind those attributes to properties that are managed in your ViewModel.