WPF绑定IntegerUpDown更新数据库整数字段仅±1步长生效问题
根因1:数据库更新方法错误获取药品ID
ChangeNumberOfDrugInDB方法中,药品ID错误从全局的SelectedDrug获取,而非传入的当前变更的drug参数:
// 错误写法 int drug_id = SelectedDrug.drug_id; // 正确写法 int drug_id = drug.drug_id;
快速调整数值、连续点击加减按钮时,UI线程选中状态更新和后台数据库更新存在时序差,会出现拿错药品ID的情况,导致只有第一次±1的变更成功写入,后续变更要么写到错误的药品上,要么因为ID匹配不到被静默忽略,最终只看到±1的修改效果。
根因2:drug_storage类属性未实现变更通知
使用BindingList监听变更时,如果列表内元素的属性没有实现INotifyPropertyChanged接口,BindingList不会触发ItemChanged类型的事件。当前逻辑能触发更新完全依赖SelectedDrug切换的副作用,数值变更的事件传递不稳定,快速变更时很容易丢失事件。
修复方法:让drug_storage实现INotifyPropertyChanged,并在drug_quantity、is_selected等需要绑定的属性的setter中触发属性变更通知:
public partial class drug_storage : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } [NotMapped] private int quantity = 1; [NotMapped] public int drug_quantity { get { return quantity; } set { quantity = value; NotifyPropertyChanged(); } } // is_selected属性也按相同结构修改 }
根因3:初始状态下tag和drug_quantity不同步
drug_storage初始化时drug_quantity默认值为1,tag默认值为0,首次加载数据后没有把tag同步为当前数据库中存储的drug_quantity值,会导致首次变更时逻辑异常。
修复方法:加载药品数据后手动将tag赋值为当前drug_quantity的值,或者在类构造函数中同步初始值:
public drug_storage() { PMR_infusions_drugs = new HashSet<PMR_infusions_drugs>(); tag = quantity; // 初始状态同步 }
可选优化:避免高频触发数据库更新
如果用户手动输入大数值、或连续快速点击加减按钮,当前逻辑会每一步都触发数据库写入,性能很差。可以给IntegerUpDown加UpdateSourceTrigger=LostFocus,让数值只有在输入完成、控件失去焦点时才同步到数据源,减少不必要的数据库操作:
<lc1:IntegerUpDown x:Name="iudQuantity" Minimum="1" Increment="1" Value="{Binding drug_quantity, Mode=TwoWay, UpdateSourceTrigger=LostFocus}" Margin="3" Visibility="{Binding IsChecked, ElementName=checkbox, Converter={StaticResource BooleanToVisibilityConverter}}" ValueChanged="SelectComboBoxItem" />
内容的提问来源于stack exchange,提问作者Fedor Isaev

