【问题标题】:Textbox value changed from Viewmodel not reflected on UI从 Viewmodel 更改的文本框值未反映在 UI 上
【发布时间】:2017-03-08 18:42:04
【问题描述】:

我有一个文本框,文本绑定到 ViewModel 中的一个属性。用户可以手动输入文本或从剪贴板粘贴。 我解析用户输入的文本(我使用 UpdateSourceTrigger=PropertyChanged)并用换行符分割文本。

问题:当用户点击回车时,一切正常。但是当我尝试处理粘贴的文本时,一旦我看到第一个“\n”,我就会尝试将它分成不同的字符串并清除文本框。在 ViewModel 中,文本设置为 string.empty,但它不会反映在 UI 上。

代码有什么问题?我知道在自己的 setter 属性中编辑文本不是好的编码习惯,但是我该怎么做呢?

这里是sn-p的代码:

XAML

    <TextBox AcceptsReturn="True" VerticalAlignment="Stretch" BorderBrush="Transparent"
             Text="{Binding TextBoxData, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}">
        <TextBox.InputBindings>
            <KeyBinding Key="Enter" Command="{Binding OnNewLineCommand}"/>
        </TextBox.InputBindings>
    </TextBox>

视图模型:

     public string TextBoxData
        {
            get
            {
                return _textBoxData;
            }
            set
            {
                _textBoxData = value;
                RaisePropertyChanged("TextBoxData");
                if(_textBoxData != null && _textBoxData.Contains("\n"))
                {
                    OnNewLineCommandEvent(null);
                }
            }
        }

    public DelegateCommand<string> OnNewLineCommand
    {
        get
        {
            if (_onNewLineCommand == null)
            {
                _onNewLineCommand = new DelegateCommand<string>(OnNewLineCommandEvent);
            }
            return _onNewLineCommand;
        }
    }

    private void OnNewLineCommandEvent(string obj)
    {
        if (_textBoxData != null && _textBoxData.Length > 0)
        {
            List<string> tbVals = _textBoxData.Split('\n').ToList();
            foreach (string str in tbVals)
            {
                ListBoxItems.Add(new UnitData(str.Trim()));
            }
            TextBoxData = string.Empty;
        }
    }

谢谢,

RDV

【问题讨论】:

  • 你的 ViewModel 是否实现了 INotifyPropertyChanged?
  • 您是否尝试在 setter 中的 OnNewLineCommandEvent 之后调用 RaisePropertyChanged?
  • 是的,我的 VM 实现了 INotifyPropertyChanged——它被称为 RaisePropertyChanged。是的,我尝试在 OnNewLineCommandEvent 之后调用 RaisePropertyChanged,但它也没有帮助
  • 您的代码完全适合我。我不相信 gremlins,所以你的代码和我的代码之间肯定有所不同。这类事情出错的最常见方式是 DataContext 不是您认为的那样——而且我没有足够的代码来知道您的 XAML sn-p 从何处获取其 DataContext。如果您在 TextBoxData 的设置器中设置断点,那么当您在文本框中输入时肯定会被命中吗?
  • 让我们先假设大项目中有特定的东西导致了特定的问题。如果“事情变慢”到永远不会调用事件处理程序的程度,我几乎不认为该应用程序将完全可用。你在大项目中尝试过绑定跟踪吗?在大项目中,如果你给TextBoxData 一个默认值(“Blah blah”之类的),这个值最初会出现在文本框中吗?

标签: wpf mvvm dependency-properties


【解决方案1】:

我发现了这个问题。如果我尝试在其设置器中修改文本框值并且值未更改,则它不会反映在 UI 上。下面可能有助于更好地解释这一点:

  1. 最初,当 UI 启动时,VM 中的文本框值设置为“ABC”。
  2. 用户在 UI 中将此值更改为“XYZ”。
  3. 在 VM 设置器中,程序员检查文本框的值是否为“XYZ”,然后将其更改回“ABC”--> 这在我的情况下失败了。 VM 中文本框的值已更改为“ABC”,但 UI 仍会显示“XYZ”。

解决方案:在 VM 中,不要将值设置回“ABC”,而是将其设置为“ABC”(注意额外的空格)-> 这将更改 UI 值。

更新的虚拟机代码:

        private bool _isTextValChanged = false;
    private void OnNewLineCommandEvent(string obj)
    {
        if (_textBoxData != null && _textBoxData.Length > 0)
        {
            List<string> tbVals = _textBoxData.Split('\n').ToList();
            foreach (string str in tbVals)
            {
                ListBoxItems.Add(new UnitData(str.Trim()));
            }
            //This will toggle textbox value and updated value will be reflected on the UI.
            if (_isTextValChanged)
                TextBoxData = " ";
            else
                TextBoxData = string.Empty;

            _isTextValChanged = !_isTextValChanged;
        }
    }

谢谢,

RDV

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    相关资源
    最近更新 更多