2010-08-11 36 views
6

Tôi nhận được một InvalidOperationException ('DeferRefresh' không được phép trong một giao dịch AddNew hoặc EditItem.) Từ datagrid của tôi khi tôi cố gắng chỉnh sửa giá trị của một cột hộp combo. Các mục tôi đang hiển thị tất cả có một tham chiếu đến một mục khác trong cùng một danh sách vì vậy đây là những gì tôi đang sử dụng combobox cho. Nó được gắn với cùng một bộ sưu tập như datagrid. Ứng dụng của tôi tôi đang làm việc là nhắm mục tiêu .NET 3.5, nhưng tôi đã đặt cùng một ví dụ giống hệt nhau trong .NET 4 kể từ khi DataGrid được tích hợp. Đây là mã cho các mục trong datagrid:WPF DataGrid ComboBox gây ra InvalidOperationException

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; 
    } 
} 

Đây là mã trong cửa sổ của tôi:

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)); 
    } 
} 

và cuối cùng XAML của tôi:

<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> 

Cảm ơn trước cho bất kỳ sự trợ giúp bạn có thể cung cấp!

+1

Điều này dường như được kết nối với các sự cố được báo cáo trên Connect (https://connect.microsoft.com/VisualStudio/feedback/details/591125/datagrid-exception-on-validation-failure-deferrefresh-is-not-allowed) và Diễn đàn MSDN (http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/187b2b8f-d403-4bf3-97ad-7f93b4385cdf/); nhưng đây là giải pháp thanh lịch nhất! –

+0

Tôi đã có vấn đề này bởi vì tôi đã nhầm lẫn ràng buộc DataGrid và DataGridComboBoxColumn của tôi vào cùng một bộ sưu tập. – Maxence

Trả lời

3

Tôi đã tìm hiểu cách khắc phục sự cố này.

Tôi tạo ra một CollectionViewSource như thế này trong Window.Resources tôi:

<Window.Resources> 
    <CollectionViewSource x:Key="itemSource" Source="{Binding Path=Items}"/> 
</Window.Resources> 

Sau đó, thay đổi định nghĩa cột combobox của tôi như sau: chuỗi

<DataGridComboBoxColumn Header="Opposite Item" Width="*" DisplayMemberPath="Name" SelectedValuePath="ID" SelectedValueBinding="{Binding Path=OppositeID}" ItemsSource="{Binding Source={StaticResource itemSource}}"/> 
2

Hãy thử sau đây trước khi gọi Refersh trên CollectionView hoặc DataGridXYZ.Items

DataGridX.CommitEdit(); 

DataGridX.CancelEdit(); 

Làm việc cho tôi.

+0

Mã được đăng chỉ là một minh chứng ngắn về vấn đề này. Ứng dụng thực sự sử dụng mvvm và cách tiếp cận này có nghĩa là gắn các trình xử lý sự kiện và như vậy. – aalex675