2010-08-11 12 views
6

Obtengo una InvalidOperationException ('DeferRefresh' no está permitida durante una transacción AddNew o EditItem) desde mi cuadrícula de datos cuando intento editar el valor de una columna de cuadro combinado. Los elementos que estoy mostrando tienen una referencia a otro elemento en la misma lista, así que esto es para lo que estoy usando el cuadro combinado. Está vinculado a la misma colección que la cuadrícula de datos. Mi aplicación en la que estoy trabajando apunta a .NET 3.5, pero he creado un ejemplo que es exactamente el mismo en .NET 4 ya que está integrada en la cuadrícula de datos. Aquí está el código para elementos en la cuadrícula de datos: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; 
    } 
} 

Este es el código en la ventana de mi:

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

y finalmente mi 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> 

Gracias de antemano por cualquier ayuda que puede ofrecer!

+1

Esto parece estar relacionado con los problemas informados en Connect (https://connect.microsoft.com/VisualStudio/feedback/details/591125/datagrid-exception-on-validation-failure-deferrefresh-is-not-allowed) y los foros de MSDN (http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/187b2b8f-d403-4bf3-97ad-7f93b4385cdf/); ¡pero esta es de lejos la solución más elegante! –

+0

Tuve este problema porque había enlazado por error mis DataGrid y DataGridComboBoxColumn a la misma colección. – Maxence

Respuesta

3

Descubrí cómo solucionar este problema.

he creado un CollectionViewSource como esta en mi Window.Resources:

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

Entonces me cambió la definición de columna de cuadro combinado a lo siguiente:

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

Trate siguiente secuencia antes de llamar Refersh en CollectionView o DataGridXYZ.Items

DataGridX.CommitEdit(); 

DataGridX.CancelEdit(); 

funcionó para mí.

+0

El código publicado fue solo una breve demostración del problema. La aplicación real usa mvvm y este enfoque significaría adjuntar controladores de eventos y tal. – aalex675