22

I've been reading about this at least for 4 hours, and seems to be the list type, but I have a situation:

A ObservableCollection that has a collection property.

I define the first DataGrid, and in the section

<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:

  1. If try to modify DataGrid1 cells it allow me.
  2. If try to modify DataGrid2 cells it throw me this exception '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:

    <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>
4

9 回答 9

22

我试过这个,问题是你已经将你的 Level2 集合初始化为Hashset<>. IEditableCollectionView.EditItem()尝试更新中的项目时引发此错误Hashset<>。我将集合初始化为List<>,它工作正常。

我不确定为什么它无法更新哈希集中的项目,需要更深入地研究它。但是更改Hashset<>toList<>将修复此错误。

希望能帮助到你

谢谢

于 2013-09-03T19:12:11.927 回答
13

你可以试试这个。将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 的例外。在此 RoutedEvent 使用其无效的 OriginalSource 冒泡之前取消此 RoutedEvent 可阻止该错误在其轨道中发生。

于 2013-11-13T11:45:02.800 回答
7

感谢@nit,他给了我正确的道路。当然,问题在于 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}}"

唯一正在播出的是如何制作通用转换器,但现在它工作正常。

于 2013-09-04T14:58:11.887 回答
7

我也通过使用解决了这个问题IsReadOnly="True"

于 2015-09-03T06:42:38.177 回答
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);
    }
}
于 2015-03-31T19:02:05.690 回答
2

用更短的方式你可以写:

DataGrid.BeginningEdit += (s, ss) => ss.Cancel = true;
于 2018-02-12T13:42:15.603 回答
1

您可以设置 IsReadOnly 属性。也许不会发生异常...在 xaml 文件中尝试..

IsReadOnly="True"
于 2015-01-30T05:20:31.567 回答
0

看到没有人发布这个,答案是因为您绑定到的集合需要实现IList(并且可能ICollection)。

这是由于(我也相信)的非通用(认为object)性质。DataGridCollectionView

于 2022-01-20T16:19:15.237 回答
-3

我解决了这个问题,将我的数据网格置于只读模式

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

……

于 2015-02-05T19:43:41.287 回答