C# 绑定到 WPF DataGrid 时,此视图不允许 DataGrid 版本“EditItem”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18578254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
DataGrid edition 'EditItem' is not allowed for this view` when bound to a WPF DataGrid
提问by Juan Pablo Gomez
I've been reading about this at least for 4 hours, and seems to be the list type, but I have a situation:
我已经阅读了至少 4 个小时,似乎是列表类型,但我有一个情况:
A ObservableCollection that has a collection property.
具有集合属性的 ObservableCollection。
I define the first DataGrid, and in the section
我定义了第一个 DataGrid,并在部分
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<!-- second Datagrid here, binding to Level2 property of my Observable collection -->
</DataTemplate>
<DataGrid.RowDetailsTemplate>
Everything goes fine, all things on screen as I expected... but:
一切顺利,屏幕上的一切都如我所料......但是:
- If try to modify DataGrid1 cells it allow me.
- If try to modify DataGrid2 cells it throw me this exception
'EditItem' is not allowed for this view
- 如果尝试修改 DataGrid1 单元格,它允许我。
- 如果尝试修改 DataGrid2 单元格,它会向我抛出此异常
'EditItem' is not allowed for this view
What am I missing ?
我错过了什么?
This is my model:
这是我的模型:
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 Code:
编辑: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>
采纳答案by Juan Pablo Gomez
Tks to @nit who give me the right path. Of course the problem reside on the base Type of EF collections
向@nit 致谢,他们给了我正确的道路。当然,问题在于 EF 集合的基本类型
Hashet< T >And Datagrid need at least a List< T >, changing all my classes "those generated by Entity framework", give to me another problem, must make changes manually, and I have a lot of them.
Hashet< T >和 Datagrid 至少需要一个List< T >,改变我所有的类“那些由实体框架生成的”,给我另一个问题,必须手动进行更改,我有很多。
My solution was to create a converter, that made the dirty work for me:
我的解决方案是创建一个转换器,这对我来说是肮脏的工作:
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;
}
}
And put it on the binding of my Datagrid2:
并将其放在我的 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}}"
The only thing on the air is how to make a generic converter, but for now it works fine.
唯一在播的是如何制作通用转换器,但现在它工作正常。
回答by Nitin
I tried this and the problem is that you have initialized your Level2 collection as Hashset<>
. IEditableCollectionView.EditItem()
throws this error while trying to update item in Hashset<>
.
I initialized the collection as List<>
and it was working fine.
我试过了,问题是你已经将你的 Level2 集合初始化为Hashset<>
. IEditableCollectionView.EditItem()
尝试更新 中的项目时引发此错误Hashset<>
。我将集合初始化为List<>
,它运行良好。
I am not sure why it is not able to update item in hashset, need to look deeper into it. But changing the Hashset<>
to List<>
will fix this error.
我不确定为什么它无法更新 hashset 中的项目,需要更深入地研究它。但是更改Hashset<>
为List<>
将修复此错误。
Hope it helps
希望能帮助到你
Thanks
谢谢
回答by ouflak
You might try this. Attach a BeginningEdit handler to your DataGrid and point to this code:
你可以试试这个。将一个 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;
}
This will only hit if you somehow manage to physically tap down on the border of the cell. The event's OriginalSource is a Border, and I think what may happen here is instead of a TextBox, or other editable element being the source as expected, this un-editable Border comes through for editing, which causes an exception that is buried in the 'EditItem is not allowed' exception. Canceling this RoutedEvent before it can bubble on through with its invalid OriginalSource stops that error occurring in its tracks.
只有当您以某种方式设法物理点击单元格的边界时,这才会命中。事件的 OriginalSource 是一个 Border,我认为这里可能发生的事情不是 TextBox,或者其他可编辑元素作为预期的源,这个不可编辑的 Border 会通过编辑,这会导致隐藏在 ' 中的异常EditItem 是不允许的例外。在它可以通过其无效的 OriginalSource 冒泡之前取消此 RoutedEvent 可以阻止该错误发生在其轨道中。
回答by Joy
you can set IsReadOnly property. maybe Exception not occur... try it in xaml file..
您可以设置 IsReadOnly 属性。也许异常不会发生......在xaml文件中尝试......
IsReadOnly="True"
回答by olavooneto
I resolved this putting my datagrid in readonly mode
我解决了这个问题,将我的数据网格置于只读模式
<DataGrid
Name="dtgBulkInsert"
CanUserSortColumns="True"
Height="300" Visibility="Collapsed" IsReadOnly="True">
....
....
回答by Guish
Here is a generic Converter that I used
这是我使用的通用转换器
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);
}
}
回答by Shouket Ali
I also solved this problem by using IsReadOnly="True"
.
我也通过使用解决了这个问题IsReadOnly="True"
。
回答by Amirhossein Yari
In shorter way you can write:
用更短的方式你可以写:
DataGrid.BeginningEdit += (s, ss) => ss.Cancel = true;