Вопрос:
Я читал об этом, по крайней мере, в течение 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> Лучший ответ:
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}}»
Единственное, что в эфире – это сделать общий конвертер, но на данный момент он отлично работает.
Ответ №1
Я попробовал это, и проблема в том, что вы инициализировали свою коллекцию Level2 как Hashset<>. IEditableCollectionView.EditItem() выдает эту ошибку при попытке обновить элемент в Hashset<>.
Я инициализировал коллекцию как List<>, и она отлично работала.
Я не уверен, почему он не может обновить элемент в hashset, нужно глубже вникать в него. Но изменение Hashset<> до List<> исправит эту ошибку.
Надеюсь, что это поможет
Спасибо
Ответ №2
Вы можете попробовать это. Присоедините обработчик 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, останавливает эту ошибку, возникающую в его дорожках.
Ответ №3
Я также решил эту проблему с помощью IsReadOnly=»True».
Ответ №4
Вот общий конвертер, который я использовал
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); } } Ответ №5
вы можете установить свойство IsReadOnly. возможно Исключение не происходит…
попробуйте в файле xaml.
IsReadOnly=»True» Ответ №6
Короче, вы можете написать:
DataGrid.BeginningEdit += (s, ss) => ss.Cancel = true; Ответ №7
Я видел эту ошибку в 3 случаях
case1: эта ошибка отображается, если дважды щелкнуть сетку данных затем (настраиваемая сетка данных, которая содержит обработанные данные, такие как анализ)
Просто установите в Datagrid IsReadOnly = “True”
case2: эта ошибка, отображаемая после редактирования сетки данных, должна быть установлена во время RowEditEnding
(sender as DataGrid).CommitEdit(DataGridEditingUnit.Row);
case3: эта ошибка отображается после события RowEditEnding, затем должна увидеть, куда сетка данных перезагружает данные; это может произойти, если источник данных или сетка данных уже используются, и мы пытаемся переопределить данные вручную
Дайте мне знать, если какие-либо новые случаи вы видели
Ответ №8
Я решил это поставить мой datagrid в режиме readonly
<DataGrid Name=»dtgBulkInsert» CanUserSortColumns=»True» Height=»300″ Visibility=»Collapsed» IsReadOnly=»True»>
….