2010-08-11 10 views
6

Ricevo un'eccezione InvalidOperationException ('DeferRefresh' non è consentita durante una transazione AddNew o EditItem.) Dal mio datagrid quando provo a modificare il valore di una colonna della casella combinata. Gli articoli che sto visualizzando hanno tutti un riferimento ad un altro elemento nella stessa lista, quindi questo è quello che sto usando la combobox per. È associato alla stessa collezione di datagrid. La mia applicazione su cui sto lavorando è quella di .NET 3.5, ma ho creato un esempio che è esattamente lo stesso in .NET 4 dato che il datagrid è integrato. Ecco il codice per gli elementi nel datagrid:WPF DataGrid ComboBox causa 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; 
    } 
} 

Questo è il codice nella mia finestra:

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

e, infine, il mio 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> 

Grazie in anticipo per tutta l'assistenza che si può offrire!

+1

Questo sembra essere collegato ai problemi segnalati su Connect (https://connect.microsoft.com/VisualStudio/feedback/details/591125/datagrid-exception-on-validation-failure-deferrefresh-is-not-allowed) e i forum MSDN (http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/187b2b8f-d403-4bf3-97ad-7f93b4385cdf/); ma questo è di gran lunga la soluzione più elegante! –

+0

Ho riscontrato questo problema perché avevo erroneamente associato DataGrid e DataGridComboBoxColumn alla stessa raccolta. – Maxence

risposta

3

Ho scoperto come risolvere questo problema.

ho creato una CollectionViewSource come questa nel mio Window.Resources:

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

Poi ha cambiato la mia definizione di colonna combobox al seguente:

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

Prova seguente sequenza prima di chiamare Refersh su CollectionView o DataGridXYZ.Items

DataGridX.CommitEdit(); 

DataGridX.CancelEdit(); 

ha funzionato per me.

+0

Il codice inserito era solo una breve dimostrazione del problema. La vera applicazione utilizza mvvm e questo approccio significherebbe associare gestori di eventi e così via. – aalex675