ListView Gruppe und Kontextmenü/Command Paramter

  • WPF

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von BornToBeRoot.

    ListView Gruppe und Kontextmenü/Command Paramter

    Hallo Community,

    ich habe eine ListView mit gruppierten Items.

    Wenn ich auf den Header ein Rechtsklick mache, soll es möglich sein über das Kontextmenü einen Dialog zu öffnen und den Header umzubennen. (bis hier her kein Problem)



    Jetzt wollte ich den aktuellen Header via CommandParamter in mein ViewModel übergeben, ich weiß aber nicht genau was ich binden muss um den Header/Name zu bekommen... Mein Code sieht bis jetzt so aus:

    C#-Quellcode

    1. <ListBox>
    2. <ListBox.Resources>
    3. <ContextMenu x:Key="EditGroupContextMenu" Opened="ContextMenu_Opened" MinWidth="150">
    4. <MenuItem Header="{DynamicResource String_Edit}" Command="{Binding EditGroupCommand}" CommandParameter="{Binding //IRGENDWAS//}">
    5. <MenuItem.Icon>
    6. <Rectangle Width="16" Height="16" Fill="{DynamicResource BlackColorBrush}">
    7. <Rectangle.OpacityMask>
    8. <VisualBrush Stretch="Uniform" Visual="{IconPacks:Modern Kind=Edit}" />
    9. </Rectangle.OpacityMask>
    10. </Rectangle>
    11. </MenuItem.Icon>
    12. </MenuItem>
    13. </ContextMenu>
    14. </ListBox.Resources>
    15. ..
    16. ..
    17. <ListBox.GroupStyle>
    18. <GroupStyle>
    19. <GroupStyle.ContainerStyle>
    20. <Style TargetType="{x:Type GroupItem}">
    21. <!-- <Setter Property="ContextMenu" Value="{StaticResource EditGroupContextMenu}" /> -->
    22. <Setter Property="Template">
    23. <Setter.Value>
    24. <ControlTemplate>
    25. <Expander IsExpanded="True" Style="{StaticResource DefaultExpander}">
    26. <Expander.Header>
    27. <TextBlock Text="{Binding Name}" Style="{DynamicResource DefaultTextBlock}" ContextMenu="{StaticResource EditGroupContextMenu}" />
    28. </Expander.Header>
    29. <ItemsPresenter />
    30. </Expander>
    31. </ControlTemplate>
    32. </Setter.Value>
    33. </Setter>
    34. </Style>
    35. </GroupStyle.ContainerStyle>
    36. </GroupStyle>
    37. </ListBox.GroupStyle>
    38. </ListBox>


    Projekt zum kompilieren: github.com/BornToBeRoot/NETworkManager

    Grüße
    NETworkManager - A powerful tool for managing networks and troubleshoot network problems!

    BornToBeRoot schrieb:

    Jetzt wollte ich den aktuellen Header via CommandParamter in mein ViewModel übergeben, ich weiß aber nicht genau was ich binden muss um den Header/Name zu bekommen... Mein Code sieht bis jetzt so aus:

    Du willst den Expander.Header bekomen oder?
    Sehe ich das richtig? Du möchtest den Header des Gruppierungsexpanders ändern? Das wird nicht klappen wenn du mit {Binding Name} bindest. Wenn dann müsstest du dir ein eigenes Property im VM erstellen.
    Sorry, bin wohl gerade zu doof um dir folgen zu können. Verstehe hier gerade keinen Sinn dahinter.

    BornToBeRoot schrieb:

    Projekt zum kompilieren: github.com/BornToBeRoot/NETworkManager

    Bringt nur leider nichts wenn der gezeigt code nicht enthalten ist??
    Suche nach EditGroupContextMenu in Solution ergab z.b. 0 Treffer.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.
    Der code ist in dem Branch: github.com/BornToBeRoot/NETworkManager/tree/rename-groups

    Hinter dem ListViewItems hängt eine xml-Datei. Ich möchte die Gruppe für jedes Item umbenennen, durch einen Klick auf den Header. Dazu brauch ich aber den aktuellen Name der im Header steht, um anschließend mit einer forearch alle Items durchzugehen und zu bearbeiten.

    NETworkManager - A powerful tool for managing networks and troubleshoot network problems!
    Ganz so einfach es das aber nicht. Das "Name" bezieht sich auf die GroupDescription. Ist also auf den Namen der Gruppe gebunden.
    Das GroupNames Property der PropertyGroupDescription Klasse ist allerdings ReadOnly.

    Siehe hier: msdn.microsoft.com/en-us/libra…escription(v=vs.110).aspx

    Hierfür müsse eine Eigenlösung oder ein (wie ich finde relativ umfangreicher) Workaround erstellt werden.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.
    Kann gerade nicht probieren. Aber hast du schon versucht das ContextMenu innerhalb des Expanders zu definieren? Hier müsstest du den selben Datencontext zur Verfügung haben um auf "Name" zugreifen zu können.

    Komme erst am Abend dazu sowas zu probieren.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.
    OK, ich hab jetzt was hinbekommen, das mit den Namen ausgibt, so wie ich es haben möchte...

    C#-Quellcode

    1. ​Command="{Binding EditGroupCommand}" CommandParameter="{Binding ., RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type GroupItem}}}"


    C#-Quellcode

    1. <Style TargetType="{x:Type GroupItem}">
    2. <Setter Property="ContextMenu" Value="{DynamicResource EditGroupContextMenu}" />
    3. <Setter Property="Template">
    4. <Setter.Value>
    5. <ControlTemplate>


    C#-Quellcode

    1. public ICommand EditGroupCommand
    2. {
    3. get { return new RelayCommand(p => EditGroupAction(p)); }
    4. }
    5. private void EditGroupAction(object name)
    6. {
    7. Debug.WriteLine(((name as GroupItem).Content as CollectionViewGroup).Name);
    8. }


    Das klappt allerdings nur beim ersten Aufruf... wenn ich das erneut aufrufe für eine zweite Gruppe, wird der name der ersten angezeigt. Ne idee?
    NETworkManager - A powerful tool for managing networks and troubleshoot network problems!
    Hallo

    Sorry für die späte Rückmeldung. Hatte ein wenig Stress.

    Ich habs jetzt probiert. Und erst dachte ich mir warum sich das Binding in verbindung mit dem ContextMenu so komisch verhält.
    Tja, die Antwort ist ganz einfach. Das ContextMenu wird ähnlich einem Fenster gehandhabt. Es ist in dem Moment wo es gebunden wird nicht Teil des VisualTrees und kann sohin nur bedingt mitteln FindAscestor oder ElementeNAme gebunden werden.

    z.b. mit einem Button funzt das ganze Tadellos.

    XML-Quellcode

    1. <ListBox.GroupStyle>
    2. <GroupStyle>
    3. <GroupStyle.ContainerStyle>
    4. <Style TargetType="{x:Type GroupItem}">
    5. <Setter Property="Template">
    6. <Setter.Value>
    7. <ControlTemplate>
    8. <GroupBox>
    9. <StackPanel>
    10. <StackPanel Orientation="Horizontal">
    11. <Button Content="Test" Command="{Binding DataContext.Editcommand, ElementName=window}" CommandParameter="{Binding Name}"/>
    12. <TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="Gray" FontSize="22" VerticalAlignment="Bottom" />
    13. <TextBlock Text="{Binding ItemCount}" FontSize="22" Foreground="Green" FontWeight="Bold" FontStyle="Italic" Margin="10,0,0,0" VerticalAlignment="Bottom" />
    14. <TextBlock Text=" item(s)" FontSize="22" Foreground="Silver" FontStyle="Italic" VerticalAlignment="Bottom" />
    15. </StackPanel>
    16. <ItemsPresenter />
    17. </StackPanel>
    18. </GroupBox>
    19. </ControlTemplate>
    20. </Setter.Value>
    21. </Setter>
    22. </Style>
    23. </GroupStyle.ContainerStyle>
    24. </GroupStyle>
    25. </ListBox.GroupStyle>


    Ich würde ein Icon mit so nem Bleistift erstellen und wenn man draufklickt wird der Textblock mittels Trigger zu ner TextBox.

    Grüße
    Sascha
    Bilder
    • Screenshot_Binidng.PNG

      84,69 kB, 1.524×955, 21 mal angesehen
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.
    Vielen Dank. Habs hinbekommen. Hier eine kleine Demo:



    Du hast recht, das KontextMenü verhält sich sehr komisch, mit einem Button gehts ^^
    NETworkManager - A powerful tool for managing networks and troubleshoot network problems!