【问题标题】:ViewModel updates interrupts user interaction with bound TextBoxViewModel 更新会中断用户与绑定的 TextBox 的交互
【发布时间】:2015-07-09 16:26:01
【问题描述】:

我遇到了用户输入被绑定 ViewModel 的更新中断的问题。

ViewModel 公开一个数值每秒都在变化。这与视图中的TextBox 绑定。我们希望TextBox 显示这个值,它做得很好。

但是,当用户单击 TextBox 并尝试输入新值时,模型中的值会更新,从而导致文本框中用户输入的值被覆盖。

如何才能最轻松地解决此问题,同时在同一控件中支持用户输入和定期更新?我将不胜感激代码示例(C#/XAML)。

如果您需要更多详细信息,请询问:)

【问题讨论】:

  • 我认为这更清楚了。 “简单”的解决方案是将显示值绑定到不是 TextBox 而是另一个控件。例如,与该文本框关联的标签。否则,您将需要自定义 UserControl 或 Control,因为您正在寻找的所需行为在框架内的任何控件中都不可用。

标签: c# wpf mvvm wpf-controls wcf-binding


【解决方案1】:

当 TextBox 获得焦点(IsFocused 属性等于 true)时,我会更改绑定类型,以便它不会被更新,除非它失去焦点。

ViewModel:

 class MainViewModel : INotifyPropertyChanged
    {
        private string _name;

        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                Debug.WriteLine(value);
                OnPropertyChanged();
            }
        }

        public MainViewModel()
        {
            Task.Factory.StartNew(async () =>
            {
                for (int i = 0; i < 1000; i++)
                {

                    Name = i.ToString();
                    await Task.Delay(3000);
                }
            });
        }


        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

XAML:

<StackPanel>
    <TextBox>
        <TextBox.Style>
            <Style TargetType="TextBox">
                <Setter Property="Text" Value="{Binding Name, Mode=OneWay}"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsFocused}" Value="True">
                        <Setter Property="Text" Value="{Binding Name, Mode=OneWayToSource, UpdateSourceTrigger=LostFocus}"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBox.Style>
       </TextBox>
    <Button Content="Click"/>
</StackPanel>

我得到序列 2,3 然后我输入 56 并单击按钮,因此文本框失去焦点并将值发送到 Name 属性。调试打印以下顺序:

1 2 3 56 4

【讨论】:

  • 感谢您的意见 - 这与我想要的非常接近。我调整了您的解决方案,而不是使用 IsFocused,而是引入了一个名为 EditMode 的布尔属性,它将更改与您的解决方案类似的绑定。感谢马克西姆斯的投入!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-22
  • 1970-01-01
  • 2018-03-28
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
  • 1970-01-01
相关资源
最近更新 更多