【问题标题】:RaisePropertyChanged fails to update the UIRaisePropertyChanged 无法更新 UI
【发布时间】:2013-11-13 02:09:33
【问题描述】:

我最近一直在 MVVM Light 中开发一个应用程序。我的 XAML 中有一个 TextBox 绑定到我的 UI。我想验证任何输入并确保只输入数字。我试过以下代码:

我的文本框

<TextBox TabIndex="1" Height="23" MinWidth="410" DockPanel.Dock="Left" 
         HorizontalAlignment="Left"
         Text="{Binding Input, UpdateSourceTrigger=PropertyChanged}" 
         IsEnabled="{Binding IsEnabled}"
         AcceptsReturn="False"
         local:FocusExtension.IsFocused="{Binding IsFocused}">

在我的 ViewModel 中:

private string input;
public string Input
{
    get { return this.input; }
    set
    {
        decimal test;
        if(decimal.TryParse(value, out test))
        {
            this.input = value;
        }
        else
        {
            this.input = "";
        }

        RaisePropertyChanged("Input");
    }
}

这无法更新 UI。如果我输入 "B" 并检查调试器,它会通过设置器运行,但实际上无法更新 UI

奇怪的是,如果我在 else 块中设置 this.input = "TEST";UI 会更新,但是,如果我尝试将其设置为 ""string.Empty,或者验证前输入的值,UI更新失败。

这是设计使然吗?可能是一个错误?是不是我做错了什么?

编辑我错误地忘记在我的示例代码中包含RaisePropertyChanged。我已经更新了它。提升它不是问题,因为我已经看到调试器一直运行通过提升它并通过 getter 返回输入。

【问题讨论】:

  • 你实际上并没有提高OnPropertyChanged。这个类是否实现了IPropertyChanged
  • @neoistheone 我正在提高RaisePropertyChanged。我错误地忘了把它放在问题的代码中。
  • 这个问题已经解决了吗?我完全符合您的情况,可以确认您提出的每一个观点。

标签: c# wpf xaml mvvm mvvm-light


【解决方案1】:

我们所做的是创建了一个自定义控件,因为我们将它用于货币文本框。我警告你我没有验证这是一个好主意,或者符合 MVVM 模型,因为所有控件的操作都是在后面的代码中完成的。

在文本框的控件中,我们在 PreviewTextInput 上有一个执行此操作的事件

e.Handled = Functions.DoubleConverter(Convert.ToChar(e.Text), ((TextBox)sender).Text.Replace("$", ""));

那么对于函数(它并不完美,我仍然有一些问题)是:

static public bool DoubleConverter(char c, string str)
{
    if (!char.IsDigit(c))
    {
        if (c == '.' && (str.Contains('.')))
        {
            return true;
        }
        else if (c != '.')
        {
            return true;
        }
    }
    return false;
}

请将此作为参考,不完全是因为它是一个非常粗糙的实现。

【讨论】:

  • 我看不出这如何回答为什么 RaisPropertyChanged() 不会在我的设置器中更新 UI。 :c
  • 抱歉,我在过去花了几天时间试图弄清楚这一点,但从来没有,所以这是我能想到的最好的。希望有人知道原因。
【解决方案2】:

使用 strign 类型属性然后转换为十进制的方式,这样更容易更改:

public decimal Input
{
    get { return this.input; }
    set 
        { 
          this.input = value;
         RaisePropertyChanged("Input");
      } 
}

为了验证使用 IDataErrorInfo(阅读更多:http://blogs.msdn.com/b/wpfsdk/archive/2007/10/02/data-validation-in-3-5.aspx

【讨论】:

  • 所有优点,但 1. 未能真正回答问题,以及 2. 这不会显示为空,这可能是操作的目的。
  • @StefanDenchev 就像你说的,我宁愿清除文本框。这个答案提出了很多好处,但最终,我无法将绑定更改为小数,因为我需要稍后将其回收用于非数字输入。
猜你喜欢
  • 2019-05-21
  • 1970-01-01
  • 2016-11-05
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
  • 2014-07-10
相关资源
最近更新 更多