Spezielles Problem mit Command Binding

  • WPF MVVM
  • .NET (FX) 4.5–4.8

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von kafffee.

    Spezielles Problem mit Command Binding

    Hallo liebe Community,

    Ich habe ein kleines Problem, bei dem ich nicht mehr weiter weiss:

    Ich habe in einem Fenster zwei identische Instanzen eines UserControls, dessen DataContext auf ebenso zwei Instanzen ein und desselben ViewModels gesetzt ist:

    XML-Quellcode

    1. ​<local:MIDIMapperDeck1_2 Grid.Row="2" DataContext="{Binding MapperDeckLeft}"/>
    2. <local:MIDIMapperDeck1_2 Grid.Row="3" DataContext="{Binding MapperDeckRight}"/>


    In diesem UserControl ist ein DataGrid mit einem Button in einer der Spalten:

    XML-Quellcode

    1. <DataGrid Name="ErstesGrid" Grid.Row="1" ItemsSource="{Binding MIDIControl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    2. <DataGrid.Columns>
    3. ​[...]
    4. <DataGridTextColumn Header="MIDI-Gerät" Width="210" Binding="{Binding MIDIGeraetename, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    5. <DataGridTemplateColumn Header="Mapping..." Width="80">
    6. <DataGridTemplateColumn.CellTemplate>
    7. <DataTemplate>
    8. <Button Name="btnStartMapping" Content="Starte Mapping..." Command="{Binding DataContext.StarteMapping, ElementName=ErstesGrid}" CommandParameter="{Binding}"/>
    9. </DataTemplate>
    10. </DataGridTemplateColumn.CellTemplate>
    11. </DataGridTemplateColumn>
    12. </DataGrid.Columns>
    13. </DataGrid>


    Interessant für mich wäre jetzt dieser Part:

    Command="{Binding DataContext.StarteMapping, ElementName=ErstesGrid}"

    Über den Command bzw. dessen Parameter soll ja der Datensatz der jeweiligen Zeile übergeben werden, damit dieser im ViewModel bearbeitet werden kann.

    Mein Programm weiss jetzt aber nicht, um welche Instanz der View MIDIMapperDeck1_2 es geht und so wird immer nur der Datensatz der ersten View geändert.

    Wie kann ich da an die Sache rangehen, damit ich mit übergeben kann, um welche Instanz es geht?

    Gruss,

    kafffee
    ich hab ja immer ein MainviewModel in Form eines Singletons.
    Da kannich RelayCommands drin anlegen, und von überall anbinden. (Dieses Anbinden mit ElementName brauche ich üblicherweise nicht - ich binde ans Viewmodel, nicht an DataContexte von iwelchen Controls.)
    Der CommandParameter übergibt ja das spezielle Item.
    Da muss dann eben das MainViewmodel in seinen MIDIMapperDeck1_2s nachgucken, wo das übergebene Item herkommt.
    Hast du mir da einen Codeschnispel?

    Ich hab das so ähnlich grad mal versucht, aber erfolglos, ich bin mir nicht sicher ob ich dich richtig verstanden hab

    Ich hab im jeweiligen Konstruktor den ViewModels mitgeteilt, welche Instanz sie denn nun sind. Aber das Binding klappt jetzt nicht:

    XML-Quellcode

    1. <Button Content="...Starte Mapping" Command="{Binding StarteMapping}" CommandParameter="{Binding}"/>


    BindingExpression path error: 'StarteMapping' property not found on 'object' ''MIDIMapperDataViewModel' (HashCode=9690616)'. BindingExpression:Path=StarteMapping; DataItem='MIDIMapperDataViewModel' (HashCode=9690616); target element is 'Button' (Name=''); target property is 'Command' (type 'ICommand')

    MIDIMapperDataViewModel ist dabei der Typ der Datensätze.

    Edit:
    @ErfinderDesRades

    Ich hab das ja ein bisschen anders als du probiert. Ich hab in meinem MainViewModel das hier:

    VB.NET-Quellcode

    1. Public Property MapperDeckLeft As ViewModel.MIDIMapperSingleDeck = New ViewModel.MIDIMapperSingleDeck(1)
    2. Public Property MapperDeckRight As ViewModel.MIDIMapperSingleDeck = New ViewModel.MIDIMapperSingleDeck(2)


    Ich teile also dem ViewModel im Konstruktor mit, welche Instanz es denn jetzt ist: (1) oder (2)

    Aber das scheint eine Sackgasse zu sein. Du hast ja geschrieben:

    ErfinderDesRades schrieb:

    Da muss dann eben das MainViewmodel in seinen MIDIMapperDeck1_2s nachgucken, wo das übergebene Item herkommt.


    Also die konkrete Frage: Wie genau stellst du das an? Bin grade versucht, mir einfach zwei Views anzulegen, diese sind bei mir auch nämlich nicht sehr umfangreich, das ist eigentlich bloss das Grid drin...

    Würde mich über eine Antwort freuen :)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „kafffee“ ()

    Sorry, viel zu tun, und dann verreist.

    na, in Grundlagen - MVVM-Anwendungs-Struktur

    hier:

    XML-Quellcode

    1. <Button Grid.Column="2" Margin="3" ToolTip="Delete"
    2. Command="{Binding Source={StaticResource Mainmodel},Path= cmdDelete}"
    3. CommandParameter="{Binding DataContext, RelativeSource={RelativeSource Self}}">
    4. <Image Height="20" Source="/PersonList;component/Resources/W95MBX01.ICO" />
    5. </Button>
    Das Command ist ins MainModel gebunden, und als Parameter gibt er den DataContext des UserControls an, was die Person darstellt.
    Und der DataContext dieses UserControls ist natürlich ein Person-Datensatz.
    Dasselbe funzt auch in den Zeilen eines ListenControls (etwa DG). Da ist der DC nämlich nicht die ans ListenControl gebundene Liste, sondern - je Zeile - das einzelne Item.