WPF升级至.NET Framework 4.7.2后ComboBox异常行为求助
解决.NET Framework 4.7.2下DataGrid编辑模板中ComboBox的异常SelectionChanged触发问题
这个问题我之前处理过,本质是.NET Framework 4.7.2对WPF的DataGrid单元格编辑清理逻辑和绑定行为做了调整,导致退出单元格编辑时会额外触发一次SelectionChanged事件,且SelectedItem为null。结合你发现的“仅当Items2是当前行数据的属性时才出现”的现象,给你几个可行的解决方案:
方案一:在事件中过滤非用户操作的触发
我们可以在SelectionChanged事件处理方法里,判断这次触发是否是用户主动选择导致的,还是单元格退出编辑时的清理行为:
private void cmbTest_SelectionChanged(object sender, SelectionChangedEventArgs e) { var comboBox = sender as ComboBox; if (comboBox == null) return; // 找到ComboBox所在的DataGridCell,判断是否还处于编辑状态 var parentCell = FindVisualParent<DataGridCell>(comboBox); if (parentCell != null && !parentCell.IsEditing) { // 这是退出编辑时的自动触发,直接忽略 return; } // 这里处理真正的用户选择逻辑 // 比如获取选中项、更新数据等 } // 辅助方法:从视觉树中查找父级DataGridCell private T FindVisualParent<T>(DependencyObject child) where T : DependencyObject { var parentObj = VisualTreeHelper.GetParent(child); if (parentObj == null) return null; if (parentObj is T parent) return parent; else return FindVisualParent<T>(parentObj); }
这个方法的核心是通过判断单元格是否还在编辑状态,来过滤掉退出编辑时的无效事件触发,精准保留用户主动操作的事件。
方案二:调整ItemsSource的绑定目标
既然你发现绑定到外部DataContext(比如DataGrid的上层ViewModel)就正常,那我们可以把Items2的数据源移到DataGrid的DataContext对应的ViewModel中,然后修改ComboBox的ItemsSource绑定:
<ComboBox Name="cmbTest" DisplayMemberPath="" HorizontalAlignment="Stretch" IsEditable="True" IsEnabled="True" IsReadOnly="False" IsSynchronizedWithCurrentItem="False" <!-- 修改这里的绑定,指向DataGrid的DataContext里的Items2 --> ItemsSource="{Binding DataContext.Items2, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Margin="0" SelectedItem="{x:Null}" SelectedValue="{x:Null}" SelectedValuePath="" Text="" VerticalAlignment="Center" Visibility="Visible" SelectionChanged="cmbTest_SelectionChanged"> </ComboBox>
这种方式避免了ItemsSource和当前行数据的绑定关联,单元格退出编辑时不会因为行数据的解绑操作影响到ComboBox的SelectedItem状态,从根源上解决了问题。
方案三:使用.NET Framework兼容性开关(不推荐)
如果你不想修改代码,可以在App.config中添加兼容性配置,让WPF回退到4.7.2之前的绑定行为:
<configuration> <runtime> <AppContextSwitchOverrides value="Switch.System.Windows.Data.Binding.DoNotForceUnloadedSourceToNull=true" /> </runtime> </configuration>
不过这个开关会全局影响WPF的绑定行为,可能带来其他未知的兼容性问题,所以仅作为临时应急方案,不推荐长期使用。
内容的提问来源于stack exchange,提问作者Luca Petrini
相关产品推荐
相关产品推荐

