webentwicklung-frage-antwort-db.com.de

DataGrid-Edition 'EditItem' ist für diese Ansicht nicht zulässig, wenn an ein WPF-DataGrid gebunden

Ich habe mindestens 4 Stunden darüber gelesen und scheint der Listentyp zu sein, aber ich habe eine Situation: 

Eine ObservableCollection mit einer Auflistungseigenschaft.

Ich definiere das erste DataGrid und im Abschnitt

<DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <!-- second Datagrid here, binding to Level2 property of my Observable collection -->
    </DataTemplate>
<DataGrid.RowDetailsTemplate>

Alles läuft gut, alles auf dem Bildschirm, wie ich es erwartet hatte ... aber:

  1. Wenn Sie versuchen, DataGrid1-Zellen zu ändern, erlauben Sie mir dies.
  2. Wenn Sie versuchen, DataGrid2-Zellen zu ändern, wird diese Ausnahme ausgelöst. 'EditItem' is not allowed for this view 

Was vermisse ich ? 

Das ist mein Modell:

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

Tks an @nit die mir den richtigen Weg geben. Natürlich liegt das Problem im Basistyp EF-Sammlungen 

Hashet <T> Und Datagrid benötigt mindestens eine List <T> , die alle meine Klassen "durch das Entity Framework generierte" ändert, gibt mir ein anderes Problem, muss manuell Änderungen vornehmen und ich habe eine Viele von ihnen. 

Meine Lösung bestand darin, einen Konverter zu erstellen, der für mich die Drecksarbeit machte:

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;
    }
}

Und lege es auf die Bindung meines 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}}"

Das einzige, was in der Luft ist, ist, wie man einen generischen Konverter herstellt, aber für den Moment funktioniert es gut.

7

Ich habe dies versucht und das Problem ist, dass Sie Ihre Level2-Sammlung als Hashset<> initialisiert haben. IEditableCollectionView.EditItem() gibt diesen Fehler aus, während versucht wird, das Element in Hashset<>..__ zu aktualisieren. Ich habe die Sammlung als List<> initialisiert, und es hat gut funktioniert.

Ich bin mir nicht sicher, warum es nicht möglich ist, ein Element im Hashset zu aktualisieren. Ich muss es genauer untersuchen. Wenn Sie jedoch Hashset<> in List<> ändern, wird dieser Fehler behoben.

Ich hoffe es hilft

Vielen Dank

17
Nitin

Sie könnten dies versuchen. Hängen Sie einen BeginningEdit-Handler an Ihr DataGrid an und verweisen Sie auf diesen Code:

    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;
    }

Dies trifft nur dann zu, wenn Sie den Rand der Zelle physisch nach unten klopfen. Die OriginalSource des Ereignisses ist eine Grenze, und ich denke, was hier passieren kann, ist, anstatt wie erwartet eine TextBox oder ein anderes bearbeitbares Element als Quelle. Diese nicht bearbeitbare Begrenzung kommt zum Bearbeiten durch, was eine Ausnahme verursacht, die im ' EditItem ist keine Ausnahme erlaubt. Wenn Sie dieses RoutedEvent abbrechen, bevor es mit seiner ungültigen OriginalSource durchgeblasen werden kann, wird der Fehler in den Spuren angezeigt. 

9
ouflak

Ich habe dieses Problem auch mit IsReadOnly="True" gelöst. 

4
Shouket Ali

Hier ist ein generischer Konverter, den ich verwendet habe

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);
    }
}
3
Guish

sie können die IsReadOnly-Eigenschaft festlegen. Vielleicht tritt keine Ausnahme auf ... Versuchen Sie es in XAML-Datei ..

IsReadOnly="True"
1
Joy

Auf kürzere Weise können Sie schreiben:

DataGrid.BeginningEdit += (s, ss) => ss.Cancel = true;
0