Dynamische Controls in Abhängigkeit einer Property (Wert aus Enum)

  • WPF
  • .NET (FX) 4.5–4.8

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von Nofear23m.

    Dynamische Controls in Abhängigkeit einer Property (Wert aus Enum)

    Ich habe in meiner Anwendung ein Enum innerhalb einer Klasse, die Klasse hat eine Property von diesem Enum-Typ

    C#-Quellcode

    1. public class MeineKlasse
    2. {
    3. public enum NestedButtonTyp
    4. {
    5. KeinButton = 0,
    6. EinButton,
    7. ZweiButton
    8. }
    9. private NestedButtonTyp _buttonTyp;
    10. public NestedButtonTyp ButtonTyp { get => _buttonTyp; set => SetProperty(ref _buttonTyp, value); }
    11. }

    In meinem MainWindow möchte ich abhängig von der Property ButtonTyp entweder keinen, einen oder zwei Button darstellen.
    Aktuell habe ich das so gelöst, dass ich einfach "alle drei" Button ins MainWindow einfüge und dann mit einem Converter entscheide, welcher Button gerade sichtbar ist.

    XML-Quellcode

    1. <Grid>
    2. .....
    3. <!--"dynamische" Darstellung-->
    4. <!--nur ein Button-->
    5. <Button Content="Eins von Eins"
    6. Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}, Path=MeinObjekt.ButtonTyp, Converter={StaticResource TypEinButtonToVisibility}}"/>
    7. <!--zwei Button-->
    8. <Grid Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}, Path=MeinObjekt.ButtonTyp, Converter={StaticResource TypZweiButtonToVisibility}}">
    9. <Grid.ColumnDefinitions>
    10. <ColumnDefinition/>
    11. <ColumnDefinition/>
    12. </Grid.ColumnDefinitions>
    13. <Button Content="Eins von Zwei" />
    14. <Button Grid.Column="1" Content="Zwei von Zwei" />
    15. </Grid>
    16. </Grid>

    Die Converter:
    Spoiler anzeigen

    C#-Quellcode

    1. public class ButtonTypEinButtonToVisibilityConverter : IValueConverter
    2. {
    3. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    4. {
    5. if (value.GetType() != typeof(MeinNamespace.MeineKlasse.NestedButtonTyp))
    6. return Visibility.Collapsed;
    7. return (MeinNamespace.MeineKlasse.NestedButtonTyp)value == MeinNamespace.MeineKlasse.NestedButtonTyp.EinButton ? Visibility.Visible : Visibility.Collapsed;
    8. }
    9. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    10. {
    11. throw new NotImplementedException();
    12. }
    13. }
    14. public class ButtonTypZweiButtonToVisibilityConverter : IValueConverter
    15. {
    16. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    17. {
    18. if (value.GetType() != typeof(MeinNamespace.MeineKlasse.NestedButtonTyp))
    19. return Visibility.Collapsed;
    20. return (MeinNamespace.MeineKlasse.NestedButtonTyp)value == MeinNamespace.MeineKlasse.NestedButtonTyp.ZweiButton ? Visibility.Visible : Visibility.Collapsed;
    21. }
    22. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    23. {
    24. throw new NotImplementedException();
    25. }
    26. }


    Diese Lösung finde ich irgendwie eher suboptimal und bin nicht so ganz zufrieden damit.
    Ich hatte auch schon über DataTemplates nachgedacht, komme da aber nicht wirklich zu einer Lösung.

    Ich hänge noch Bilder an wie das ganze aussehen soll; und auch noch eine TestSolution die meinen aktuellen Stand vereinfacht zeigt.
    Vielleicht hat ja jemand eine geniale Idee.
    Bilder
    • ZweiButton.png

      10,28 kB, 786×443, 17 mal angesehen
    • KeinButton.png

      8,13 kB, 786×443, 17 mal angesehen
    • EinButton.png

      8,64 kB, 786×443, 17 mal angesehen
    Dateien
    • TestSolution.zip

      (26,2 kB, 11 mal heruntergeladen, zuletzt: )
    Dumm ist der, der dumm ist. Nicht andersrum!
    Hy

    ich würde das mit einem Trigger erledigen. Per Trigger kannst du ganz angenehm Steuern ob ein Button sichtbar sein soll oder nicht. Für Trigger gibt's ein Kapitel in meinem Tutorial..

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Daran habe ich auch schon gedacht, aber dann müsste ich trotzdem erstmal alle "physisch" erzeugen/darstellen oder nicht?
    Dann wäre der einzige Unterschied bloß, dass ich es einmal mit Converter und einmal mit Trigger mache.
    Wobei ich schon einen Vorteil bei dem Trigger sehe, dass ich nicht erst wieder mehrere separate Converter-Klassen erstellen muss.

    Hatte nur gedacht, dass es vielleicht auch etwas in Richtung DataTemplate gibt.
    Dumm ist der, der dumm ist. Nicht andersrum!

    Schmittmuthelm schrieb:

    Hatte nur gedacht, dass es vielleicht auch etwas in Richtung DataTemplate gibt.

    Für DataTemplates braucht du einen Typ. Also Klassen. Mit Enums klappt das nicht. Leider.
    Du kannst nur ein DateTemplate auf den Enumerator selbst legen, nicht aber auf den Wert.

    XML-Quellcode

    1. <DataTemplate DataType="{x:Type MyEnumType}">
    2. <TextBlock x:Name="valueText"/>
    3. <DataTemplate.Triggers>
    4. <DataTrigger Binding="{Binding}" Value="{x:Static MyEnumType.ValueOne}">
    5. <Setter TargetName="valueText" Property="Text" Value="First Value" />
    6. </DataTrigger>
    7. <DataTrigger Binding="{Binding}" Value="{x:Static MyEnumType.ValueTwo}">
    8. <Setter TargetName="valueText" Property="Text" Value="Second Value" />
    9. </DataTrigger>
    10. </DataTemplate.Triggers>
    11. </DataTemplate>


    Edit: Oder du schreibst dir einen DataTemplateSelector.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##