UserControl DependencyProperty mit Type Boolean

  • WPF

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

    UserControl DependencyProperty mit Type Boolean

    Hallo,

    ich habe schon sehr viel gesucht, auch gefunden aber leider habe ich bei diese Erklärungen immer den Zusammenhang bzw. Sinn verloren. Klar, es fehlen auch die Englischkenntnisse um im Kontext zu bleiben.
    Da gibt's es noch sehr viel mehr aber der Anfang gehört dem DependencyProperty mit Type Boolean in einer UserControl.

    In einem einfachen Beispiel habe ich ein DependencyProperty mit Getter und Setter an einen Label Content(OneWay) gebunden in einem Window.
    Das darin enthaltene DataGrid hat 2 Events (MouseEnter, MouseLeave) die das Dependency aktualisieren sollen, und dann den Label Content.
    Das scheint funktioniert zu haben, ob das ganz richtig war bin ich mir nicht so sicher. In einem UserControl klappts nicht mehr.

    Beispiel1

    VB.NET-Quellcode

    1. Public Shared ReadOnly canScrollIntoViewTypeProperty As DependencyProperty = _
    2. DependencyProperty.RegisterAttached("canScrollIntoViewType", GetType(Boolean), _
    3. GetType(MainWindow), _
    4. New PropertyMetadata(True, New PropertyChangedCallback(AddressOf canScrollIntoViewTypePropertyChanged)))
    5. Public Property canScrollIntoViewType() As Boolean
    6. Get
    7. Return CBool(GetValue(canScrollIntoViewTypeProperty))
    8. End Get
    9. Set(value As Boolean)
    10. SetValue(canScrollIntoViewTypeProperty, value)
    11. End Set
    12. End Property
    13. Public Shared Sub canScrollIntoViewTypePropertyChanged(ByVal sender As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
    14. If Not e.OldValue.Equals(e.NewValue) Then
    15. sender.SetValue(canScrollIntoViewTypeProperty, e.NewValue)
    16. End If
    17. End Sub
    18. Private Sub DataGrid_MouseEnter(sender As Object, e As MouseEventArgs)
    19. Me.canScrollIntoViewType = False
    20. End Sub
    21. Private Sub DataGrid_MouseLeave(sender As Object, e As MouseEventArgs)
    22. Me.canScrollIntoViewType = True
    23. End Sub



    Nun habe ich das DependencyProperty in ein UserControl gelegt und es hat die Bindung verloren, ging also nicht mehr.

    Also habe ich den 2.Typ(Bezeichnung dafür kenne ich nicht) den ich kannte genommen und es ging, dummerweise scheint dabei das Property unter Dauerfeuer zu stehen da der
    alt und neu Vergleich irgendwie nicht greift

    Beispiel2

    Visual Basic-Quellcode

    1. Private Shared Sub canScrollIntoViewChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
    2. If Not e.NewValue.Equals(e.OldValue) Then
    3. Dim canScrollIntoView As FrameworkElement = DirectCast(d, FrameworkElement)
    4. If CBool(e.NewValue) Then
    5. canScrollIntoView.IsEnabled = True
    6. Else
    7. canScrollIntoView.IsEnabled = False
    8. End If
    9. End If
    10. End Sub
    11. Public Shared Function canScrollIntoViewGetType(obj As DependencyObject) As Boolean
    12. Return CBool(obj.GetValue(canScrollIntoViewProperty))
    13. End Function
    14. Public Shared Sub canScrollIntoViewSetType(obj As DependencyObject, value As Boolean)
    15. obj.SetValue(canScrollIntoViewProperty, value)
    16. End Sub
    17. Public Shared ReadOnly canScrollIntoViewProperty As DependencyProperty = DependencyProperty.RegisterAttached("canScrollIntoViewType", _
    18. GetType(Boolean), _
    19. GetType(MainJobTableUc), _
    20. New PropertyMetadata(True, New PropertyChangedCallback(AddressOf canScrollIntoViewChanged)))
    21.  
    22.  
    23. Private Sub DataGrid_MouseEnter(sender As Object, e As MouseEventArgs)
    24. Me.SetValue(canScrollIntoViewProperty, False)
    25. End Sub
    26. Private Sub DataGrid_MouseLeave(sender As Object, e As MouseEventArgs)
    27. Me.SetValue(canScrollIntoViewProperty, True)
    28. End Sub


    Vielleicht kann jemand helfen
    Wo liegt denn bei diesen DependencyProperties der Unterschied?
    Macht das einen Unterschied in welchem Control die welche Typen von DependencyProperties vorhanden sind?
    Wann werden diese DependencyProperties mit "New PropertyMetadat" benutzt und in welchen Situationen; Wenn ich es so verstanden habe nur bei einfachen Datentypen(Boolean, String...)?
    Wieso hat Beispiel 1 überhaupt ein Binding beim ersten mal und verliert es dann?
    Woher kommt bei Beispiel 2 der Dauerfeuer Effect?
    In Beispiel 2 steht "DependencyProperty.RegisterAttached", bei einem Test hat das auch ohne "Attached" funktioniert, warum das?
    Das bitte nicht ;( , ist das total verkehrt von mir verstanden?

    Grüße

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

    Hallo

    Sehe ich das richtig. Du willst wenn der User mit der Maus über das Datagrid fährt Quasi nach draußen ins Fenster wo das UCL liegt was verändert über Binding. Man war der Satz jetzt blöd geschrieben. Naja

    Im UserControls so:

    VB.NET-Quellcode

    1. Public Property CanScrollIntoView As Boolean
    2. Get
    3. Return GetValue(CanScrollIntoViewProperty)
    4. End Get
    5. Set(ByVal value As Boolean)
    6. SetValue(CanScrollIntoViewProperty, value)
    7. End Set
    8. End Property
    9. Public Shared ReadOnly CanScrollIntoViewProperty As DependencyProperty =
    10. DependencyProperty.Register("CanScrollIntoView",
    11. GetType(Boolean), GetType(uclTest),
    12. New PropertyMetadata(True))
    13. Private Sub MyGrid_MouseEnter(sender As Object, e As MouseEventArgs)
    14. CanScrollIntoView = False
    15. End Sub
    16. Private Sub MyGrid_MouseLeave(sender As Object, e As MouseEventArgs)
    17. CanScrollIntoView = True
    18. End Sub


    Im Windows musst du dann nur noch Binden, hier gilt aber das nur OneWay einen sinn macht:

    XML-Quellcode

    1. <Label Content="{Binding ElementName=myUcl, Path=CanScrollIntoView, Mode=OneWay}"/>
    2. <local:uclTest x:Name="myUcl"/>


    Grüße
    Sascha

    ​Kleiner Nachtrag: Du kannst in den Metadaten einige Dinge Festlegen. z.b. das kein TwoWay als Default genommen werden soll oder das die WPF weis das Änderungen an diesem Property kein neues rendern des Views erfordert.

    ​z.b. Metadaten erstellen mit: ​Private Shared meta As New FrameworkPropertyMetadata With {.DefaultValue = True, .BindsTwoWayByDefault = False, .AffectsRender = False}

    und dann das DP:

    VB.NET-Quellcode

    1. ​Public Shared ReadOnly CanScrollIntoViewProperty As DependencyProperty =
    2. DependencyProperty.Register("CanScrollIntoView",
    3. GetType(Boolean), GetType(uclTest),
    4. meta)


    Sehr gute Erklärung wie ich finde gibt es hier: openbook.rheinwerk-verlag.de/v…arp_2012/1997_26_003.html

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

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

    hi, der "Naja-Satz" ist das logische Ergebnis aus meiner Vorgabe, ich arbeite noch dran.

    Ok, in meinem Beispiel2 (ehemals Beispiel Typ2) war das Dauerfeuer dieser dumme Querdenker, habs erst jetzt gesehen.

    VB.NET-Quellcode

    1. If CBool(e.NewValue) Then
    2. canScrollIntoView.IsEnabled = True
    3. else...


    Jetzt klappt dein Beispiel, mein Beispiel(aber nicht zu gebrauchen da Casten nicht notwendig), erstmal gut.
    Danke für den Anreiz zum Code-Design.
    Für "einfache Daten-Typen" ist dann "PropertyMetadata" nötig und ein DependencyProperty.Register.
    Mit dem PropertyChangedCallback hab ich dann auch die Prüfung und mehr möglchkeiten falls benötigt.
    Aber die ginge dann einfacher im Setter mit

    VB.NET-Quellcode

    1. If CBool(GetValue(CanScrollIntoViewProperty)).Equals(value) Then Exit Property


    Somit fallen fast alle Fragen eigentlich weg.

    Das DependencyProperty.RegisterAttached wird dann nur bei Controls benötigt, kann das sein?

    Wenn ich vorangegangenes so richtig verstanden habe
    mache ich für FrameworkPropertyMetadata und Coerce.. demnächst lieber ein neues Thema auf, passt hier nicht rein.

    Grüße
    Hallo

    mojoReini schrieb:

    Für "einfache Daten-Typen" ist dann "PropertyMetadata" nötig und ein DependencyProperty.Register.

    Hat jetzt nix mit dem Datentypen zu tun. Du MUSST es ja immer übergeben. Aber entweder machst du dir vorher eben eine Varbiable oder du übergibst nur New PropertieMetaData(True) und setzt nur das Property DefaultValue weil die (ich glaube) zweite Überladung des Contructors von PropertyMetaData den DefaultValue als Parameter erwartet.

    mojoReini schrieb:

    Aber die ginge dann einfacher im Setter mit

    ​Solltest du dir nicht Angewöhnen. Wenn da was nicht läuft wie soll suchst du lange. Ich machs auf jeden Fall nicht. Bringt im Endeffekt auch nichts.
    ​Ich erstelle ein DependencyProperty damit ich darauf Binden kann. Und ich finde wenn OnNotifyPropertyChanged geworfen wird sollte der Setter auch durchlaufen.

    mojoReini schrieb:

    Das DependencyProperty.RegisterAttached wird dann nur bei Controls benötigt, kann das sein?

    ​Kommt darauf an. Du benötigst es nur wenn du bei Registrieren des DP etwas machen willst. Stell dir das vor wie OnLoad. (soweit ich weis!!)


    Grüße
    ​Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.
    Zu Antwort auf Aber die ginge dann einfacher im Setter mit :
    Wenn bei einem Setter der Wert gespeichert werden soll(in XML, DbTable UPDATE), währe es doch sinnvoller auf Equal zu prüfen und bei Paarigkeit ein Exit zu machen, würde doch dann keinen Sinn machen den Wert in der XML auf Paarigkeit zu prüfen.
    Fürs Code testen macht man was ich gar nicht mache(kein Programmierer), eine Unit Test. Schließlich soll der Code laufen um auch auf eine Exception zu reagieren. Beim schreiben, oder allgemein wenns sein muss, in einer Datenbank gibts dafür ROLLBACK.

    Grüße
    Reiner
    Hallo

    Wenn bei einem Setter der Wert gespeichert werden soll(in XML, DbTable UPDATE), währe es doch sinnvoller auf Equal zu prüfen

    Du bist hier aber in keinem XML, DbTable oder ähnlichem. Du bist in einem UserControl. Und ein UserControl oder ein Control SPEICHERT NIE(!!!).

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