ViewModel - Einheiten realisieren

  • WPF

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von florian03.

    ViewModel - Einheiten realisieren

    Hallo,

    komme heute mal wieder mit einer Frage:

    (Btw. ich weiß nicht ob es das richtige Unterforum ist, es geht halt um MVVM)

    Ich habe in meinem ViewModel ein Property Volume in dem ich eine Volumen Angabe in ml speichern will. Dieses Property habe ich ganz normal an eine Textbox gebunden.
    Da von der Programmlogik sowohl sehr große als auch sehr kleine Angaben möglich sind möchte ich dem Benutzer in einer ComboBox die Möglichkeit geben, die Einheit (ml, l) auszuwählen.

    Jetzt würde ich , da ich das noch nie so richtig gemacht habe, so ein Control gerne erstellen.
    Also einfach eine Textbox und hinten dran eine Combobox mit den Einheiten.


    Dieses Control sollte dann die Eigenschaften Value bieten, die den aktuellen Wert in ml angibt, EGAL welche Einheit gerade ausgewählt wurde.
    Allerdings brauche ich auch noch eine Eigenschaft um auf den aktuellen Wert in der Textbox und aktuelle Einheit zuzugreifen.
    Nur fehlt mir hier irgendwie der Ansatz (habe irgendwas von AttachedProperties) gehört, womit man solche Eigenschaften, auch bindbar, machen kann).

    Wenn man mir dabei helfen könnte, wäre ich echt dankbar.

    PS: Ich habe dann aber immer noch die Möglichkeit z.B. die Schriftgröße der Textbox zu ändern, also von "auserhalb" des Controls.

    Viele Grüße
    Florian
    ----

    WebApps mit C#: Blazor
    Hallo

    Jetzt gibt es zwei Möglichkeiten. Ein Usercontrol oder ein Customcontrol.

    Ein Customcontrol ist etwas komplizierter aber auch nicht so schlimm, ich würde aber in diesem Fall ein UserControl mit den entsprechenden DependencyProperties erstellen und fertig. Das entsprechende Kapitel gibt es ja in meiner Reihe schon.

    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. ##

    Hallo,

    genau das war das, wonach ich gesucht habe.
    Habe jetzt mal ein einfaches UserControl erstellt:

    XAML:

    XML-Quellcode

    1. ​<UserControl x:Class="TexboxesWithUnits.uclVolumeTextbox"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    5. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    6. xmlns:local="clr-namespace:TexboxesWithUnits"
    7. mc:Ignorable="d"
    8. d:DesignHeight="450" d:DesignWidth="800">
    9. <Grid>
    10. <Grid.ColumnDefinitions>
    11. <ColumnDefinition Width="*"/>
    12. <ColumnDefinition Width="10"/>
    13. <ColumnDefinition Width="Auto"/>
    14. </Grid.ColumnDefinitions>
    15. <Grid.RowDefinitions>
    16. <RowDefinition Height="Auto"/>
    17. </Grid.RowDefinitions>
    18. <TextBox Padding="10,5" Text="{Binding EnteredValue, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:uclVolumeTextbox}}}"></TextBox>
    19. <ComboBox ItemsSource="{Binding AviableUnits, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:uclVolumeTextbox}}}"
    20. SelectedItem="{Binding SelectedUnit, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:uclVolumeTextbox}}}"
    21. Grid.Column="2" ></ComboBox>
    22. </Grid>
    23. </UserControl>


    CodeBehind:

    C#-Quellcode

    1. public partial class uclVolumeTextbox : UserControl
    2. {
    3. public uclVolumeTextbox()
    4. {
    5. InitializeComponent();
    6. }
    7. public double EnteredValue
    8. {
    9. get { return (double)GetValue(EnteredValueProperty); }
    10. set { SetValue(EnteredValueProperty, value); }
    11. }
    12. // Using a DependencyProperty as the backing store for EnteredValue. This enables animation, styling, binding, etc...
    13. public static readonly DependencyProperty EnteredValueProperty =
    14. DependencyProperty.Register("EnteredValue", typeof(double), typeof(uclVolumeTextbox), new PropertyMetadata(0.0));
    15. public Unit SelectedUnit
    16. {
    17. get { return (Unit)GetValue(SelectedUnitProperty); }
    18. set { SetValue(SelectedUnitProperty, value); }
    19. }
    20. // Using a DependencyProperty as the backing store for SelectedUnit. This enables animation, styling, binding, etc...
    21. public static readonly DependencyProperty SelectedUnitProperty =
    22. DependencyProperty.Register("SelectedUnit", typeof(Unit), typeof(uclVolumeTextbox), new PropertyMetadata(Unit.ml));
    23. public IEnumerable<Unit> AviableUnits
    24. {
    25. get
    26. {
    27. return Enum.GetValues(typeof(Unit)).Cast<Unit>();
    28. }
    29. }
    30. public double Value
    31. {
    32. get
    33. {
    34. return ((int)SelectedUnit) * EnteredValue;
    35. }
    36. }
    37. // Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc...
    38. public static readonly DependencyProperty ValueProperty =
    39. DependencyProperty.Register("Value", typeof(double), typeof(uclVolumeTextbox), new PropertyMetadata(0.0));
    40. }
    41. public enum Unit
    42. {
    43. ml = 1,
    44. l = 1000,
    45. cl = 10
    46. }


    Funktioniert auch alles bestens, ich bekomme, wenn ich Value abrufe auch immer den passenden Wert.
    Allerdings habe ich in einer TestApp ein Label an die Value Eigenschaft meier Textbox gebunben.. Dieses Label wurde aber nicht aktuallisiert, wenn ich einen Wert geändert habe. wo muss ich des denn einstellen?

    Aber ich muss jetzt schon, wenn ich eine andere Textgröße will, dafür ein extra DeProp erstellen?

    Vielen Dank schon mal für die Hilfe und Grüße
    Florian
    ----

    WebApps mit C#: Blazor

    florian03 schrieb:

    an die Value Eigenschaft meier Textbox gebunben.. Dieses Label wurde aber nicht aktuallisiert, wenn ich einen Wert geändert habe.

    Wie ich im Video zu diesem Kapitel auch erklärt habe sind die Getter und Setter des Property eines DependencyProperty tabu. Genau wegen solchen dingen.
    Mach das über den Handler der DependencyProperty mit SetValue

    florian03 schrieb:

    Aber ich muss jetzt schon, wenn ich eine andere Textgröße will, dafür ein extra DeProp erstellen?

    Oder du bindest die Textgröße der Textbox an die des UserControls und setzt es auf dieses von außen :rolleyes:

    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. ##

    Nofear23m schrieb:

    Mach das über den Handler der DependencyProperty mit SetValue


    Stehe gerade auf dem Schlauch, wie meist du das?
    Habe in die set-Methoden von SelectedUnit und ​EnteredValue folgenden Code eingefügt:

    C#-Quellcode

    1. ​SetValue(ValueProperty, ((int)SelectedUnit) * EnteredValue)


    Das ist mein gesammtes CodeBehind

    C#-Quellcode

    1. public partial class uclVolumeTextbox : UserControl
    2. {
    3. public uclVolumeTextbox()
    4. {
    5. InitializeComponent();
    6. }
    7. public double EnteredValue
    8. {
    9. get { return (double)GetValue(EnteredValueProperty); }
    10. set { SetValue(EnteredValueProperty, value); SetValue(ValueProperty, ((int)SelectedUnit) * EnteredValue); }
    11. }
    12. // Using a DependencyProperty as the backing store for EnteredValue. This enables animation, styling, binding, etc...
    13. public static readonly DependencyProperty EnteredValueProperty =
    14. DependencyProperty.Register("EnteredValue", typeof(double), typeof(uclVolumeTextbox), new PropertyMetadata(0.0));
    15. public Unit SelectedUnit
    16. {
    17. get { return (Unit)GetValue(SelectedUnitProperty); }
    18. set { SetValue(SelectedUnitProperty, value); SetValue(ValueProperty, ((int)SelectedUnit) * EnteredValue); }
    19. }
    20. // Using a DependencyProperty as the backing store for SelectedUnit. This enables animation, styling, binding, etc...
    21. public static readonly DependencyProperty SelectedUnitProperty =
    22. DependencyProperty.Register("SelectedUnit", typeof(Unit), typeof(uclVolumeTextbox), new PropertyMetadata(Unit.ml));
    23. public IEnumerable<Unit> AviableUnits
    24. {
    25. get
    26. {
    27. return Enum.GetValues(typeof(Unit)).Cast<Unit>();
    28. }
    29. }
    30. public double Value
    31. {
    32. get
    33. {
    34. return (double)GetValue(ValueProperty);
    35. }
    36. }
    37. // Using a DependencyProperty as the backing store for Value. This enables animation, styling, binding, etc...
    38. public static readonly DependencyProperty ValueProperty =
    39. DependencyProperty.Register("Value", typeof(double), typeof(uclVolumeTextbox), new PropertyMetadata(0.0));
    40. }
    41. public enum Unit
    42. {
    43. ml = 1,
    44. l = 1000,
    45. cl = 10
    46. }
    ----

    WebApps mit C#: Blazor
    Ach so, vielen Dank!
    Jetzt hab ich es verstanden - musste in der Tutorialreihe noch mal eins zurück - da stand es auch super erklärt!

    Vielen Dank an euch alle und Grüße
    Florian
    ----

    WebApps mit C#: Blazor