Редактирование 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">
....