C# WinForms使用INotifyPropertyChanged数据绑定的数据刷新冲突问题求助
解决方案:避免服务器推送数据覆盖用户正在编辑的TextBox内容
核心思路是通过标记编辑状态,区分用户输入和服务器推送两种数据更新场景,在用户编辑时暂存服务器数据,待编辑完成后再同步。
1. 修改ValueBinding类,添加编辑状态标记与暂存逻辑
using System.ComponentModel; using System.Runtime.CompilerServices; public class ValueBinding : INotifyPropertyChanged { private int _value; private int? _pendingServerValue; // 暂存服务器推送的待更新值 private bool _isUserEditing; public int Value { set { if (value != _value) { if (_isUserEditing) { // 用户正在编辑,暂存服务器数据,不立即更新UI _pendingServerValue = value; } else { // 非编辑状态,直接更新值并通知UI _value = value; OnPropertyChanged(nameof(Value)); } } } get => _value; } public bool IsUserEditing { get => _isUserEditing; set { if (_isUserEditing != value) { _isUserEditing = value; // 编辑结束时,应用暂存的服务器数据(如果有) if (!_isUserEditing && _pendingServerValue.HasValue) { _value = _pendingServerValue.Value; _pendingServerValue = null; OnPropertyChanged(nameof(Value)); } } } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 调整绑定逻辑与TextBox事件处理
// 初始化绑定(保留原绑定逻辑,微调UpdateMode优化输入体验) BindingList<ValueBinding> valueList = new BindingList<ValueBinding>(); ValueBinding valueBinding = new ValueBinding(); valueList.Add(valueBinding); // 设置DataSourceUpdateMode为OnValidation,确保用户输入仅在验证后更新数据源 textBox1.DataBindings.Add("Text", valueList[0], "Value", true, DataSourceUpdateMode.OnValidation); // 绑定TextBox的Enter/Leave事件,标记编辑状态 textBox1.Enter += (sender, e) => valueBinding.IsUserEditing = true; textBox1.Leave += (sender, e) => valueBinding.IsUserEditing = false; // 修改Enter键处理逻辑,确保输入合法后同步数据源并发送请求 private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { TextBox textBox = sender as TextBox; if (e.KeyChar == (char)Keys.Enter) { // 验证输入是否为合法整数 if (int.TryParse(textBox.Text, out int newValue)) { // 更新绑定的数据源,确保数据一致性 valueBinding.Value = newValue; // 发送修改请求到服务器 SendChangemessage(newValue.ToString()); // 结束编辑状态,允许后续服务器数据同步 valueBinding.IsUserEditing = false; } e.Handled = true; } }
3. 确保服务器数据推送在UI线程执行
WinForms控件仅能在UI线程更新,若服务器数据接收在后台线程,需通过Invoke切换到UI线程:
// 服务器数据接收回调示例 private void OnServerDataReceived(int newServerValue) { if (textBox1.InvokeRequired) { textBox1.Invoke(new Action<int>(OnServerDataReceived), newServerValue); } else { valueBinding.Value = newServerValue; } }
关键逻辑说明
- 编辑状态标记:通过
IsUserEditing区分用户是否正在操作TextBox,服务器推送数据时若处于编辑状态则暂存。 - 暂存机制:
_pendingServerValue保存编辑期间的服务器数据,待编辑结束后自动同步到UI。 - 数据验证:在Enter键处理中添加输入合法性校验,避免非法值更新数据源。
内容的提问来源于stack exchange,提问作者Akio Zhao
相关产品推荐
相关产品推荐

