【问题标题】:WPF DataGrid ComboBox causes InvalidOperationExceptionWPF DataGrid ComboBox 导致 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>

提前感谢您提供的任何帮助!

【问题讨论】:

标签: wpf datagrid combobox invalidoperationexception


【解决方案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】:

    CollectionViewDataGridXYZ.Items 上调用Refersh 之前尝试以下顺序

    DataGridX.CommitEdit();
    
    DataGridX.CancelEdit();
    

    为我工作。

    【讨论】:

    • 发布的代码只是对问题的简短演示。真正的应用程序使用 mvvm,这种方法意味着附加事件处理程序等。
    猜你喜欢
    • 1970-01-01
    • 2013-06-30
    • 2013-02-03
    • 1970-01-01
    • 2011-02-28
    • 2011-05-06
    • 2012-02-09
    • 2010-11-01
    相关资源
    最近更新 更多