0

我的 WPF 应用程序中的 MVVM 模式和命令有问题。问题不在于 MVVM 模式,而在于我的 GUI 上正在发生的事情。我解释一下情况:

我的应用程序可以 DoStuff 到某些文件。我有一个带有函数的类DoStuff(int limit)。我的用户用户界面有以下项目:

  • AButton DoStuffBtn开始解析。
  • ATextBox LimitTxt填写一个限制。
  • ACheckBox LimitChk启用或禁用限制。

当您“取消选中”LimitChk时,然后LimitTxt.Text = ""LimitTxt.IsEnabled = false。当您再次“检查”时LimitChkLimitTxt.IsEnabled = false文本仍然为空,直到您填写某些内容。

我已经阅读了许多关于 WPF 和 MVVM 中的命令的教程,但我似乎无法将我的案例倒入那个模型中。我给出的示例实际上只是我 UI 的一小部分,但我似乎也不能很好地做到这一点。

我不断遇到以下问题:

  • 我需要两个CommandsLimitChk启用和禁用)还是只需要一个(切换)?
  • 如果我绑定一个intto LimitTxt,如果我将它设为空并禁用它会发生什么?
  • 按下DoStuff(Int32.Parse(LimitTxt.Text))时使用它是一种干净的方法吗?DoStuffBtn
  • 如果我在 上使用两个命令,确定是否启用的功能LimitChk会发生什么?CanExecute()ICommandLimitChk

所以主要问题是:我描述的情况如何适合使用 WPF 中的命令的一个很好的模式?

我看过的关于 WPF、Commands 和 MVVM 的一些链接:


到目前为止我所理解的是,我必须尽可能地远离 UI。甚至像 UI 这样的东西也会影响 UI。即取消选中LimitChk禁用LimitText。尽管如此,我认为我应该在与 UI 相关的信息和操作以及实际上与必须完成的实际工作有关的内容之间保持区别。

4

2 回答 2

3

我认为您感到困惑...您在这里不需要任何命令,只需使用绑定即可。

  • 我需要两个 LimitChk 命令(启用和禁用)还是只需要一个(切换)?

你不需要。LimitEnabled只需在您的 ViewModel 中创建一个属性,并将其绑定CheckBox到它(IsChecked="{Binding LimitEnabled}"

  • 如果我将一个 int 绑定到 LimitTxt,如果我将其设为空并禁用它会发生什么?

禁用它没有任何效果。如果您将其TextBox设为空,则绑定将失败,因为无法将空字符串转换为 int(至少不能使用默认转换器)

  • 按下 ParseBtn 时仅使用 Parse(Int32.Parse(LimitTxt.Text)) 是一种干净的方法吗?

你不需要。Limit只需在您的 ViewModel 中创建一个属性,并将其绑定TextBox到它。您可能想要添加一个ExceptionValidationRuleBinding以便它突出显示无效输入。

该按钮不是必需的,当TextBox失去焦点时会自动完成解析(如果您使用默认值UpdateSourceTrigger)。如果要自定义解析方式,可以创建自定义转换器以在绑定中使用。

于 2010-01-22T16:52:05.040 回答
1

只是一些高级的想法,省略了颜色和对齐属性、WrapPanels 等多余的东西。

您的 ViewModel 有几个属性:

public bool? LimitIsChecked { get; set; }
public bool LimitTextIsEnabled { get; set; }  //to be expanded, below
public ICommand ParseCommand { get; private set; } // to be expanded, below
public string LimitValue { get; set; } // further explanation, below

您的 XAML 具有 CheckBox 和 TextBox 定义,例如:

<CheckBox Content="Limit Enabled" IsChecked="{Binding LimitIsChecked}" />
<TextBox Text="{Binding LimitValue}" IsEnabled="{Binding LimitIsEnabled}" />
<Button Content="Parse" Command="{Binding ParseCommand}" />

您需要像这样初始化 ParseCommand:

this.ParseCommand = new DelegateCommand<object>(parseFile);

现在,让我们也填写 LimitTextIsEnabled 属性:

public bool LimitTextIsEnabled {
    // Explicit comparison because CheckBox.IsChecked is nullable.
    get { return this.LimitIsChecked == true; }
    private set { }
}

然后,您的parseFile方法会将LimitValue属性的值传递给执行实际解析的逻辑。

我在LimitValue这里将属性声明为字符串,以避免使用显式转换器或其他验证代码混淆代码。您可以选择以几种不同的方式处理“LimitValue 是一个有效的 int”验证/转换。

当然,我还没有完全实现这一点,但我想概述一种模式,您不使用命令来更新其他小部件的状态。相反,将这些属性绑定到在您的 ViewModel 中管理的属性。

于 2010-01-22T16:56:24.853 回答