2010-08-11 3 views
6

콤보 상자 열의 값을 편집하려고하면 InvalidOperationException이 발생합니다 (AddNew 또는 EditItem 트랜잭션 중에 'DeferRefresh'가 허용되지 않습니다.). 내가 보여주고있는 모든 항목은 같은 목록에있는 다른 하나의 항목에 대한 참조를 가지고 있으므로 이것이 제가 콤보 상자를 사용하고있는 것입니다. DataGrid와 동일한 컬렉션에 바인딩됩니다. .NET 3.5를 대상으로하는 응용 프로그램을 작성 중이지만 DataGrid가 기본으로 제공되므로 .NET 4에서 정확히 동일한 예제를 작성했습니다. 다음은 DataGrid의 항목 코드입니다.WPF DataGrid ComboBox로 인해 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; 
    } 
} 
결국 내 XAML

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

과 : 당신이 제공 할 수있는 모든 지원을 사전에

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

감사

이 내 창에 코드입니다!

+1

이것은 Connect (https://connect.microsoft.com/VisualStudio/feedback/details/591125/datagrid-exception-on-validation-failure-deferrefresh-is-not-allowed)에서보고 된 문제와 관련이있는 것 같습니다.) 및 MSDN 포럼 (http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/187b2b8f-d403-4bf3-97ad-7f93b4385cdf/); 그러나 이것은 가장 우아한 해결 방법입니다! –

+0

실수로 DataGrid와 DataGridComboBoxColumn을 동일한 컬렉션에 바인딩했기 때문에이 문제가 발생했습니다. – Maxence

답변

3

나는이 문제를 해결하는 방법을 발견했다.

나는 나의 Window.Resources이 같은 CollectionViewSource을 만들어 : CollectionView 또는 DataGridXYZ.ItemsRefersh를 호출하기 전에

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

보십시오 다음과 같은 순서 :

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

는 그런 다음에 내 콤보 상자의 열 정의를 변경

DataGridX.CommitEdit(); 

DataGridX.CancelEdit(); 

저를 위해 일했습니다.

+0

게시 된 코드는 문제의 간단한 데모였습니다. 실제 응용 프로그램은 mvvm을 사용하며이 접근 방법은 이벤트 처리기 등을 연결하는 것을 의미합니다. – aalex675

관련 문제