WPF DataGrid ComboBox 导致 InvalidOperationException
Posted
技术标签:
【中文标题】WPF DataGrid ComboBox 导致 InvalidOperationException【英文标题】:WPF DataGrid ComboBox causes InvalidOperationException 【发布时间】:2022-01-11 09:51:57 【问题描述】:当我尝试编辑组合框列的值时,我从我的数据网格中收到 InvalidOperationException(在 AddNew 或 EditItem 事务期间不允许使用“DeferRefresh”。)。我展示的所有项目都引用了同一列表中的另一个项目,所以这就是我使用组合框的目的。它与数据网格绑定到同一个集合。我正在开发的应用程序针对 .NET 3.5,但我已经整理了一个与 .NET 4 中完全相同的示例,因为数据网格是内置的。以下是数据网格中项目的代码:
public class TestItem : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
private int m_ID;
private string m_Name;
private int m_OppositeID;
public int ID
get return m_ID;
set
m_ID = value;
RaisePropertyChanged("ID");
public string Name
get return m_Name;
set
m_Name = value;
RaisePropertyChanged("Name");
public int OppositeID
get return m_OppositeID;
set
m_OppositeID = value;
RaisePropertyChanged("OppositeID");
public TestItem(int id, string name, int oppID)
ID = id;
Name = name;
OppositeID = oppID;
这是我窗口中的代码:
public partial class MainWindow : Window, INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
private ObservableCollection<TestItem> m_Items;
public ObservableCollection<TestItem> Items
get return m_Items;
set
m_Items = value;
RaisePropertyChanged("Items");
public MainWindow()
InitializeComponent();
this.DataContext = this;
Items = new ObservableCollection<TestItem>();
Items.Add(new TestItem(0, "Fixed", 0));
Items.Add(new TestItem(1, "Left Side", 2));
Items.Add(new TestItem(2, "Right Side", 1));
最后是我的 xaml:
<Window x:Class="DataGrid_Combo_Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid ItemsSource="Binding Path=Items" AutoGenerateColumns="False">
<DataGrid.Resources>
<Style x:Key="ItemsSourceStyle" TargetType="ComboBox">
<Setter Property="ItemsSource" Value="Binding Path=DataContext.Items, RelativeSource=RelativeSource AncestorType=x:Type Window"/>
</Style>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Binding="Binding Path=ID" Header="ID" Width="*"/>
<DataGridTextColumn Binding="Binding Path=Name" Header="Name" Width="*"/>
<DataGridComboBoxColumn Header="Opposite Item" Width="*" DisplayMemberPath="Name" SelectedValuePath="ID" SelectedValueBinding="Binding Path=OppositeID" ElementStyle="StaticResource ItemsSourceStyle" EditingElementStyle="StaticResource ItemsSourceStyle"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
提前感谢您提供的任何帮助!
【问题讨论】:
这似乎与 Connect(connect.microsoft.com/VisualStudio/feedback/details/591125/…) 和 MSDN 论坛(social.msdn.microsoft.com/Forums/en-US/wpf/thread/…) 上报告的问题有关;但这是迄今为止最优雅的解决方法! 我遇到了这个问题,因为我错误地将我的 DataGrid 和 DataGridComboBoxColumn 绑定到同一个集合。 【参考方案1】:我发现了如何解决这个问题。
我在 Window.Resources 中创建了一个这样的 CollectionViewSource:
<Window.Resources>
<CollectionViewSource x:Key="itemSource" Source="Binding Path=Items"/>
</Window.Resources>
然后将我的组合框列定义更改为以下内容:
<DataGridComboBoxColumn Header="Opposite Item" Width="*" DisplayMemberPath="Name" SelectedValuePath="ID" SelectedValueBinding="Binding Path=OppositeID" ItemsSource="Binding Source=StaticResource itemSource"/>
【讨论】:
【参考方案2】:在CollectionView
或DataGridXYZ.Items
上调用Refersh
之前尝试以下顺序
DataGridX.CommitEdit();
DataGridX.CancelEdit();
为我工作。
【讨论】:
发布的代码只是对问题的简短演示。真正的应用程序使用 mvvm,这种方法意味着附加事件处理程序等。以上是关于WPF DataGrid ComboBox 导致 InvalidOperationException的主要内容,如果未能解决你的问题,请参考以下文章
wpf datagrid 一列下拉多选comboBox怎么实现??
WPF DataGrid 每行ComboBox 内容不同的设置方法
WPF MVVM 将 ComboBox 绑定到 Datagrid 选定项