web-dev-qa-db-ja.com

DataGridエディション 'EditItem'は、WPF DataGridにバインドされている場合、このビューでは許可されません

私はこれについて少なくとも4時間読んでおり、リストタイプのようですが、私は状況があります:

コレクションプロパティを持つObservableCollection。

最初のDataGridを定義し、セクションで

<DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <!-- second Datagrid here, binding to Level2 property of my Observable collection -->
    </DataTemplate>
<DataGrid.RowDetailsTemplate>

すべてがうまくいき、すべてが画面上に表示されました。

  1. DataGrid1セルを変更しようとすると、許可されます。
  2. DataGrid2セルを変更しようとすると、この例外がスローされます'EditItem' is not allowed for this view

何が欠けていますか?

これは私のモデルです:

public partial class Level1
{
    public Level1()
    {
        this.Level2 = new HashSet<Level2>();
    }

    public decimal IdLevel1 { get; set; }
    public decimal IdLevel2 { get; set; }
    public string StrDescripcionTipoAsociado {get;set;}

    public virtual Level2 Level2{ get; set; }
}

public partial class Level2
{
    public decimal IdLevel1 { get; set; }
    public decimal IdLevel3 { get; set; }

    public virtual Level3 Level3{ get; set; }
}

public partial class Level3
{
    public decimal IdLevel3 { get; set; }
    public decimal NumIdConcepto {get;set;}
    public string StrDescripcionConcepto {get;set;}
}

編集:XAMLコード:

    <DataGrid Grid.Row="1" 
              ItemsSource="{Binding Level1}" 
              AutoGenerateColumns="False" 
              SelectionMode="Single"
              GridLinesVisibility="Vertical"
              CanUserAddRows="True"
              CanUserDeleteRows="True"
              x:Name="GridTipoAsociado">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Tipo de asociado" x:Name="TipoUsuarioSeleccionado">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Label Style="{StaticResource ResourceKey=FontElemNivel1}" Content="{Binding StrDescripcionTipoAsociado}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <TextBox Style="{StaticResource ResourceKey=FontElemNivel2}" Text="{Binding StrDescripcionTipoAsociado }"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
        <DataGrid.RowDetailsTemplate>
            <DataTemplate>
                <DataGrid Grid.Row="1" 
                          ItemsSource="{Binding Level2}" 
                          AutoGenerateColumns="False" 
                          SelectionMode="Single"
                          SelectionUnit="Cell"
                          GridLinesVisibility="Vertical"
                          CanUserAddRows="True"
                          CanUserDeleteRows="True"                            
                          x:Name="GridItems">
                    <DataGrid.Columns>
                        <DataGridTemplateColumn Header="Id Item">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <Label Content="{Binding NumIdConcepto}"/>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                        <DataGridTemplateColumn Header="Items">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <Label Content="{Binding Level3.StrDescripcionConcepto}"/>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                            <DataGridTemplateColumn.CellEditingTemplate>
                                <DataTemplate>
                                    <TextBox Text="{Binding Level3.StrDescripcionConcepto}"/>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellEditingTemplate>
                        </DataGridTemplateColumn>
                    </DataGrid.Columns>
                </DataGrid>
            </DataTemplate>
        </DataGrid.RowDetailsTemplate>
    </DataGrid>
18

正しい道を教えてくれる@nitへのTks。もちろん、問題はEFコレクションの基本タイプにあります

Hashet <T>そしてDatagridは少なくともList <T>を必要とし、すべてのクラスを「エンティティフレームワークによって生成されたもの」に変更し、別の問題を与え、変更を加える必要があります手動で、私はそれらの多くを持っています。

私の解決策はコンバーターを作成することでした、それは私にとって汚い仕事をしました:

public class listToObservableCollection : BaseConverter, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        HashSet<Level2> observableList = (HashSet<Level2>)value;
        return new ObservableCollection<Level2>(observableList);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return (HashSet<Level2>)value;
    }
}

public abstract class BaseConverter : MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

そして、それを私のDatagrid2のバインディングに配置します。

<!--part of my window definition--!>
xmlns:l="clr-namespace:Recursos;Assembly=Recursos"
...
<!--part of my resources section--!>
<l:listToObservableCollection x:Key="listoToObservable"/>
...
<!--part of my datagrid definition--!>
ItemsSource="{Binding Level2,Converter={StaticResource listoToObservable}}"

放送されている唯一のものは、一般的なコンバーターの作り方ですが、今のところそれはうまくいきます。

7

私はこれを試しましたが、問題はあなたのLevel2コレクションを_Hashset<>_として初期化したことです。 IEditableCollectionView.EditItem()は、_Hashset<>_のアイテムを更新しようとしたときにこのエラーをスローします。コレクションを_List<>_として初期化したところ、問題なく動作しました。

なぜハッシュセットのアイテムを更新できないのかよくわかりません。詳しく調べる必要があります。ただし、_Hashset<>_を_List<>_に変更すると、このエラーが修正されます。

それが役に立てば幸い

ありがとう

21
Nitin

あなたはこれを試すかもしれません。 BeginningEditハンドラーをDataGridに接続し、次のコードをポイントします。

    private void Grid_BeginningEdit(object sender, DataGridBeginningEditEventArgs e)
    {
        //// Have to do this in the unusual case where the border of the cell gets selected
        //// and causes a crash 'EditItem is not allowed'
        e.Cancel = true;
    }

これは、何らかの方法でセルの境界線を物理的にタップした場合にのみヒットします。イベントのOriginalSourceはボーダーであり、ここで発生する可能性があるのは、TextBoxまたは他の編集可能な要素が期待どおりにソースである代わりに、この編集不可能なボーダーが編集のために通過するため、「 EditItemは許可されていません」という例外があります。無効なOriginalSourceでバブルする前にこのRoutedEventをキャンセルすると、トラックで発生するエラーが停止します。

9
ouflak

また、IsReadOnly="True"を使用してこの問題を解決しました。

7
Shouket Ali

これが私が使った一般的なコンバータです

public class ObservableCollectionConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var observableType= typeof (ObservableCollection<>).MakeGenericType(value.GetType().GetGenericArguments());
        return Activator.CreateInstance(observableType, value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var observableType = typeof(HashSet<>).MakeGenericType(value.GetType().GetGenericArguments());
        return Activator.CreateInstance(observableType, value);
    }
}
3
Guish

isReadOnlyプロパティを設定できます。多分例外は発生しません... xamlファイルで試してください。

IsReadOnly="True"
1
Joy

より短い方法で書くことができます:

DataGrid.BeginningEdit += (s, ss) => ss.Cancel = true;
0