none
Databinding Datagrid SelectedItem RRS feed

  • Frage

  • Ich habe ein DataGrid, welches ich bereits erfolgreich an eine Collection binden konnte. Nun möchte ich gerne die ausgewählte Zeile, also SelectedItem, an ein weiteresObjekt der Klasse binden. XAML:

    SelectedItem="{Binding ElementName=My_Control, 
          Path=LocalSettings}"

    Dies funktioniert, aber nur solange, wie keine leere Zeile ausgewählt ist. Leere Zeilen benötige ich zwangsläufig, da der User neue Einträge ins DataGrid eingetragen muss. Kann mir jemand helfen, wie und wo ich das Binding so machen kann, dass keine Exception geworfen wird, wenn eine leere Zeile ausgewählt ist?

    Besten Dank für allfällige Antworten im Voraus.

    Dienstag, 23. November 2010 09:02

Antworten

  • Ich habe das Problem nun gelöst: Der User kann selber keine neuen Zeilen hinzufügen, CanUserAddRows="False".

    Neue Zeilen müssen über einen Button hinzugefügt werden. Über diesen wird zuerst ein neues Objekt erstellt, welches in die ans DataGrid gebindete Collection eingefügt wird.

    Mittwoch, 24. November 2010 10:14

Alle Antworten

  • Hast du mal die Logik innerhalb deiner LocalSettings Property überprüft, evtl. musst du dort ein NULL Wert abfangen werden!

     

    Dienstag, 23. November 2010 11:56
    Beantworter
  • Dies sollte eigentlich kein Problem sein, da mein LocalSettings mit NULL initialisiert werden kann (LocalSettings ist eine eigene Klasse).

    Es kommt folgende Fehlermeldung in der Konsole:

     

    ConvertBack cannot convert value '{NewItemPlaceholder}' (type 'NamedObject'). 
    BindingExpression:Path=LocalSettings; DataItem='MyControl' (Name='My_Control');
    target element is 'DataGrid' (Name='SequenceGrid'); target property is 'SelectedItem' (type 'Object')
    NotSupportedException:'System.NotSupportedException: TypeConverter kann nicht von MS.Internal.NamedObject konvertieren.
    Als Geübter User ist es vielleicht nicht so schwer, diese Meldung zu interpretieren. Für mich ist dies jedoch ziemlich kryptisch.

     

    Eigentlich wollte ich im Code Behind folgendes Implementieren zum Abfangen des Problems:

     

     private void SequenceGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
      {
       if (SequenceGrid.SelectedItem is LocalSettingsClass) //skip if line is empty
       {
        LocalSettings = (LocalSettingsClass)SequenceGrid.SelectedItem;
       }
      }
    Doch die oben genannte Fehlermeldung bleibt bestehen, sobald ich auf die unterste, leere Zeile im DataGrid klicke.

     

    • Bearbeitet Code4132 Dienstag, 23. November 2010 13:24 formatierung
    Dienstag, 23. November 2010 12:16
  • Es kann sein, dass das Grid kein neues Objekt anlegen kann. Was für ein Typ hat den deine Collection und die darin enhaltenen Childs?

    Ist das CanUserAddRows Property auf True gesetzt?

    Dienstag, 23. November 2010 12:46
    Beantworter
  • Danke für den Hinweis. Ich habe das CanUserAddRows Property auf True gesetzt. Leider löst dies das Problem nicht. Folgendes Verhalten zeigt sich aber nun:

    Wenn ich 2mal in die Zeile klicke (also die Zeile anwählen-> wirft oben genannte exception auf der Konsole, dann nochmals in die Zeile klicken), wird ein neues Objekt in diese Zeile eingefügt und die Fehlermeldung verschwindet.

    Die Collection hat den Typ ObservableCollection<LocalSettingsClass>. LocalSettingsClass implementiert INotifyPropertyChanged.

    Zusätzlich möchte ich, dass das jeweils ausgewählte Item des DataGrids in einem (separaten) lokalen Objekt vom Typ LocalSettingsClass gespeichert wird.

     

    Edit: Soeben habe ich in der Konsole nochmals eine Fehlermeldung entdeckt, die beim (ersten) Anwählen der leeren Zeile geworfen wird:

     

    Error: 23 : Cannot convert '{NewItemPlaceholder}' from type 
    'NamedObject' to type 'LocalSettingsClass' for 'en-US' culture with default conversions; consider using Converter property of Binding.
    NotSupportedException:'System.NotSupportedException: TypeConverter kann nicht von MS.Internal.NamedObject konvertieren.

     

    • Bearbeitet Code4132 Dienstag, 23. November 2010 13:23 Ergänzungen
    Dienstag, 23. November 2010 13:16
  • Hast du das SequenceGrid_SelectionChanged Event noch gebunden, wenn ja kommentier den Code mal aus!


    >>Zusätzlich möchte ich, dass das jeweils ausgewählte Item des DataGrids in einem (separaten) lokalen Objekt vom Typ LocalSettingsClass gespeichert wird.
    >>
    Setze den Modus für das Binding auf Mode=TwoWay, dann wird das SelectedItem auch wieder in die Variable "LocalSettings" zurückgespeichert, wenn du in dem Grid eine andere Zeile selektierst.

     

     

    Dienstag, 23. November 2010 13:23
    Beantworter
  • Leider bleibt das Problem bestehen. Es scheint gemäss Debugging keine Probleme zugeben, bis versucht wird, aus der leeren Zeile ein Objekt des Typs "LocalSettingsClass" zu erstellen und dieses dem LocalSettings-Attribut zuzuweisen.

    Ich frage mich nun, ob es irgendwie eine Möglichkeit gibt, wie man dieses Problem abfangen könnte? Vielleicht ein Converter?


    Edit:

    Vielleicht ist dieses Verhalten seitens DataGrid erwünscht. Wenn ich die leere Zeile anwähle, wird das ganze DataGrid rot umrandet. Sobald beim 2.Mal anwählen die Default-Werte eingefüllt werden (und keine Exception mehr geworfen wird), verschwindet der rote Rahmen. Ich denke langsam, ich muss mein Konzept mit diesem Binding nochmals überarbeiten.

    Bis dahin vielen Dank für die Unterstützung.

    Dienstag, 23. November 2010 13:43
  • Ich habe das Problem nun gelöst: Der User kann selber keine neuen Zeilen hinzufügen, CanUserAddRows="False".

    Neue Zeilen müssen über einen Button hinzugefügt werden. Über diesen wird zuerst ein neues Objekt erstellt, welches in die ans DataGrid gebindete Collection eingefügt wird.

    Mittwoch, 24. November 2010 10:14
  • NewItemPlaceholder ist ein festes generisches Objekt, dass standardmässig als Datenobjekt für eine neue Zeile verwendet wird. Wenn dieser NewItemPlaceholder nun bei Änderung der ausgwählten Zeile über das Binding zurück an die Quelle (MyControl) geschickt wird kommt er durch einen Converter, der versucht es nach LocalSettings zu wandeln. Da NewItemPlaceholder nicht nach LocalSettings gewandelt werden kann scheitert das.

    Wäre es möglich neben LocalSettings zusätzlich eine Property LocalSettingsInput vom Typ Object einzuführen? Für eine normale Auswahl leitet dieses den Wert and LocalSettings weiter. Ein NewItemPlaceholder ist ein Object so dass es keinen Typfehler gibt. Falls du MVVM benutzt, wäre ein "gespiegeltes" SelectedItem Property in deinem ViewModel ebenfalls vom Typ Object.

    Donnerstag, 27. Januar 2011 17:50