绑定到WPF DataGrid时,此视图不允许使用DataGrid版本的"EditItem"

Jua*_*mez 18 c# wpf xaml datagrid

我至少已经阅读了4个小时,并且似乎是列表类型,但我有一个情况:

具有集合属性的ObservableCollection.

我定义了第一个DataGrid,并在该部分中

<DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <!-- second Datagrid here, binding to Level2 property of my Observable collection -->
    </DataTemplate>
<DataGrid.RowDetailsTemplate>
Run Code Online (Sandbox Code Playgroud)

一切顺利,屏幕上的所有内容都如我所料......但是:

  1. 如果尝试修改DataGrid1单元格,它允许我.
  2. 如果尝试修改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;}
}
Run Code Online (Sandbox Code Playgroud)

编辑: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>
Run Code Online (Sandbox Code Playgroud)

Nit*_*tin 21

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

我不确定为什么它无法更新hashset中的项目,需要深入研究它.但是更改Hashset<>List<>将修复此错误.

希望能帮助到你

谢谢

  • 原因是因为将`Datagrid`的itemsource绑定到`Hashset`不会生成实现`IEditableCollectionView`的集合视图.`List`将生成一个`ListCollectionView`,_does_实现这个接口,这就是它工作的原因. (9认同)
  • 这让我陷入了困境; 在我的情况下,我只是愚蠢,并将网格绑定到LINQ查询的结果.解决方案只是将.ToList()添加到它的末尾. (2认同)

ouf*_*lak 9

你可以试试这个.将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;
    }
Run Code Online (Sandbox Code Playgroud)

只有当你以某种方式设法在细胞的边界上进行物理攻击时,才会触发.事件的OriginalSource是一个边框,我认为这里可能发生的不是TextBox,或者其他可编辑的元素是预期的源,这个不可编辑的边框进行编辑,这导致一个异常埋藏在'不允许使用EditItem'例外.取消此RoutedEvent之前,它可以通过其无效的OriginalSource冒泡,停止在其轨道中发生该错误.


Jua*_*mez 7

请给@nit谁给我正确的道路.当然问题在于基本的EF类型集合

Hashet <T> 和Datagrid至少需要一个List <T>,改变我所有的类"由Entity framework生成的那些",给我另一个问题,必须手动进行更改,而且我有很多.

我的解决方案是创建一个转换器,使我的脏工作:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

并把它放在我的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}}"
Run Code Online (Sandbox Code Playgroud)

唯一的问题是如何制作通用转换器,但现在它工作正常.


小智 7

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


Gui*_*ish 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);
    }
}
Run Code Online (Sandbox Code Playgroud)