Редактирование DataGrid 'EditItem' не разрешено для этого представления `при привязке к WPF DataGrid

Я читал об этом, по крайней мере, в течение 4 часов, и, похоже, это тип списка, но у меня есть ситуация:

A ObservableCollection, обладающий свойством коллекции.

Я определяю первый DataGrid, а в разделе

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

Все идет хорошо, все на экране, как я ожидал... но:

  • Если вы пытаетесь изменить ячейки DataGrid1, это позволяет мне.
  • Если вы пытаетесь изменить ячейки 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;}
}

EDIT: Код 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>

Ответы

Ответ 1

Tks to @nit, которые дают мне правильный путь. Конечно, проблема заключается в базе Тип коллекций EF

Hashet <T> И Datagrid нужно как минимум List <T> , изменив все мои классы, "созданные с помощью инфраструктуры Entity", дайте мне еще одну проблему, должны внести изменения вручную, и их много.

Мое решение состояло в том, чтобы создать конвертер, который сделал грязную работу для меня:

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

Единственное, что в эфире - это сделать общий конвертер, но на данный момент он отлично работает.

Ответ 2

Я попробовал это, и проблема в том, что вы инициализировали свою коллекцию Level2 как Hashset<>. IEditableCollectionView.EditItem() выдает эту ошибку при попытке обновить элемент в Hashset<>. Я инициализировал коллекцию как List<>, и она отлично работала.

Я не уверен, почему он не может обновить элемент в hashset, нужно глубже вникать в него. Но изменение Hashset<> до List<> исправит эту ошибку.

Надеюсь, что это поможет

Спасибо

Ответ 3

Вы можете попробовать это. Присоедините обработчик 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 представляет собой Border, и я думаю, что здесь может произойти то, что вместо TextBox или другого редактируемого элемента, являющегося источником, как и ожидалось, эта нередактируемая Border появляется для редактирования, что вызывает исключение, которое скрывается в ' EditItem не допускается, исключение. Отмена этого RoutedEvent до того, как он начнет пузыриться с его недействительным OriginalSource, останавливает эту ошибку, возникающую в его дорожках.

Ответ 4

Я также решил эту проблему с помощью IsReadOnly="True".

Ответ 5

Вот общий конвертер, который я использовал

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

Ответ 6

вы можете установить свойство IsReadOnly. возможно Исключение не происходит... попробуйте в файле xaml.

IsReadOnly="True"

Ответ 7

Короче, вы можете написать:

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

Ответ 8

Я видел эту ошибку в 3 случаях

case1: эта ошибка отображается, если дважды щелкнуть сетку данных затем (настраиваемая сетка данных, которая содержит обработанные данные, такие как анализ)

Просто установите в Datagrid IsReadOnly = "True"

case2: эта ошибка, отображаемая после редактирования сетки данных, должна быть установлена во время RowEditEnding

  (sender as DataGrid).CommitEdit(DataGridEditingUnit.Row);

case3: эта ошибка отображается после события RowEditEnding, затем должна увидеть, куда сетка данных перезагружает данные; это может произойти, если источник данных или сетка данных уже используются, и мы пытаемся переопределить данные вручную

Дайте мне знать, если какие-либо новые случаи вы видели

Ответ 9

Я решил это поставить мой datagrid в режиме readonly

<DataGrid 
                Name="dtgBulkInsert"
                CanUserSortColumns="True" 
                Height="300" Visibility="Collapsed" IsReadOnly="True">

....