Binding im übergeordneten UserControl

  • WPF

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

    Binding im übergeordneten UserControl

    Hey Leute, ich muss mich mal wieder melden, da ich den Wald vor lauter Bäumen nicht sehe.

    ich habe ein "NumericUpDown" als UserControl gebastelt. Funktioniert auch soweit gut. Es besteht aus zwei RepeatButtons und einer Textbox. Die Buttons inkrementieren oder dekrementieren die DependencyProperty Count jeweils um 1. Die Textbox ist mittels Binding dazu angehalten, den Wert für Count anzuzeigen. Das funktioniert super.

    Nun wollte ich diesen NumericUpDown in einem weiteren UserControl einbinden und habe dahinter eine weitere DependencyProperty (HouseCount). Also dachte ich, dass ich den Wert für Count einfach darauf binde... aber irgendwie funktioniert das nicht. Der Wert wird mir tatsächlich richtig in der Textbox angezeigt, Count ist auch entsprechend richtig gesetzt, aber Count und HouseCount gleichen sich nicht ab. Aber zu meinem Verständnis (und hier liegt vermutlich das Problem): Wenn ich beide Werte aneinander binde, müssten sie sich doch theoretisch abgleichen?

    Hier ist folgender Code im übergeordneten UC:

    XML-Quellcode

    1. <local:NumericUpDown Grid.Row="1" Grid.RowSpan="2" Count="{Binding HouseCount, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:CitizenWindow}}}" HorizontalAlignment="Center"/>


    und hier der Code des kompletten untergeordneten UC:

    XML-Quellcode

    1. <StackPanel Orientation="Horizontal">
    2. <RepeatButton Width="30" x:Name="ValueDown" Click="ValueDown_Click">
    3. -
    4. </RepeatButton>
    5. <TextBox Width="60" PreviewTextInput="TextBox_PreviewTextInput" Text="{Binding Count, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:NumericUpDown}}}" VerticalContentAlignment="Center" HorizontalContentAlignment="Right"/>
    6. <RepeatButton Width="30" x:Name="ValueUp" Click="ValueUp_Click">
    7. +
    8. </RepeatButton>
    9. </StackPanel>


    Also: ich habe im unteren UC alles über Count laufen. Nun binde ich die Variable HouseCount daran. Also müssten sie theoretisch doch gleich sein? Ich brauche die, da ich mittels HouseCount weitere Berechnungen anstellen möchte, die automatisch stattfinden sollen.
    Was also übersehe ich, damit die beiden sich angleichen?

    Wenn ich die Buttons nutze, dann erhalte ich immer ein INotifyChanged-Event von Count, nicht aber von HouseCount. :S

    Edit: Wenn ich das UC (übergeordnet) erstelle mit ​HouseCount="20" wird die Textbox auch richtig vorinitialisiert... aber es bleibt irgendwie alles in der Count-Variablen

    Padre

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

    Hallo

    Mit BindingMode=TwoWay funzt es auch nicht?

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

    hab ich tatsächlich auch versucht. Klappt nicht.

    Interessant ist, dass ich über die Initialisierung auch die entsprechenden Werte einmal setzen kann und die werden auch in Count übernommen. Wenn ich nun aber im unteren UC dann auf die Buttons klicke, ändert sich tatsächlich nur der Wert, nicht der Wert der im oberen UC gespeicherten DependencyProperty.
    Ich weiß auch nicht, ob ich da gerade irgendwas übersehen habe.

    Aber eigtl steht im XAML ja genau das so, wie es sein müsste und jeweils im UC ist dann jeweils die Variable als DependencyProperty registriert worden.

    Padre

    EDIT:
    ich bin nun einen etwas anderen Weg gegangen, der aber meiner Meinung nach nicht derjenige ist, den man bevorzugen sollte, da es andersrum ja auch gehen müsste:

    ich habe nun der Textbox im NumericUpDown ein TextChanged-Event spendiert und das nach oben gegeben und nutze im übergeordneten UC das Changed-Event und setze dort die HouseCount:

    C#-Quellcode

    1. HouseCount = (sender as NumericUpDown).Count;​

    VB.NET-Quellcode

    1. ​Dim Numeric as NumericUpDown = CType(sender, NumericUpDown)
    2. HouseCount = Numeric.Count


    Aber vielleicht kann mir ja von euch doch noch einer auf die Sprünge helfen, wie ich es anstellen kann, dass sie sich mittels binding angleichen können :) ?

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

    Hallo

    Ich kanns gerne versuchen. Da ich aber nicht weis wie du die DependencyProperties implementiert hast und wie nun die genau konstellation ist wäre es cool wenn du eine kleines Beispiel hier hochlädst und dann kann ich mir das morgen Vormittag mal gerne ansehen.

    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

    Sorry, ich hab total auf dich vergessen. :|
    Ich versuche heute dazu zu kommen.

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

    So, hatte kurz Zeit mir das anzusehen und nun weis ich wo der Denkfehler liegt.

    Du hast soweit alles richtig gemacht, bis auf eine kleinigkeit welche ich auch in meinem Tutorial zum Thema DependencyProperties erwähnt hatte.
    Der Setter oder Getter des Properties welches mit einem DependencyProperty in Verbindung steht (also ein Property welches GetValue() und SetValue() verwendet) ist tabu.

    Ein DependencyProperty funktioniert anders (siehe mein Tutorial) und muss anders gesetzt werden. Eben mit SetValue() oder aus der Instanz heraus. (Ich Erinnere.... ein DependecyProperty ist ja static)
    Hierfür gibt es die Möglichkeit einen Callback in den Property-Metadaten anzugeben.

    C#-Quellcode

    1. new PropertyMetadata(0, new PropertyChangedCallback(HouseCountChanged))


    Innerhalb dieser Methode kann man auf Änderungen einer Eigenschaft reagieren. Sonst nirgens.
    Und zwar wird in deinem Fall ein Callback für das Property HouseCount als auch für das Property Multiplicator benötigt, denn wenn sich dieser ändert muss MaxPopulation ja ebenfalls aktualisiert werden.

    Das sieht dann im Fall von HouseCount wie folgt aus:

    C#-Quellcode

    1. public static readonly DependencyProperty HouseCountProperty = DependencyProperty.Register("HouseCount", typeof(int), typeof(CitizenWindow),new PropertyMetadata(0, new PropertyChangedCallback(HouseCountChanged)));
    2. public int HouseCount
    3. {
    4. get { return (int)GetValue(HouseCountProperty); }
    5. set { SetValue(HouseCountProperty, value); }
    6. }
    7. private static void HouseCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    8. {
    9. Recalculate(d);
    10. }
    11. public static void Recalculate(DependencyObject d)
    12. {
    13. CitizenWindow ucl = (CitizenWindow)d;
    14. ucl.MaxPopulation = ucl.HouseCount * ucl.Multiplicator;
    15. }



    Falls du noch Fragen hast kannst du dich gerne melden, ich hoffe ich habe es verständlich genug erklärt.

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

    Ich musste mir dein Geschriebenes tatsächlich zweimal anschauen, bis ich begriffen habe, was mein Fehler war... aber ja, du hast Recht... ich hab den Wald vor lauter Bäumen nicht mehr gesehen... was bin ich doch für ein Schaf

    Ich musste tatsächlich auch zweimal überlegen, warum ich nicht einfach ​MaxPopulation = A * B schreiben kann, kann ich ja in der Klasse CitizenWindow doch auch... aber ja, das CitizenWindow hat die DP ja auch implementiert und in der Definition einer DP kann ich schwer auf die andere zugreifen.

    Vielen Dank. Du hast mein Verständnis wieder einmal deutlich erweitert :)
    Hallo

    Freut mich das ich helfen konnte. Ja, so ein Antworttext kann bei sowas auch schon mal etwas verwirrender sein. :)

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