Binding von Properties

  • WPF

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

    Binding von Properties

    Hallo liebe Leute,
    ich hab mich mal versucht in Sachen WPF schlau zu machen weil mir scheint, dass dem die Zukunft gehört. Nun hab ich einige Grundlagen begriffen und wollte mich jetzt mit dem Binden von Daten an die WPF-Oberfläche befassen. Da stolpere ich aber gewaltig beim Festlegen der Quelle der Binding.
    Folgendes einfaches Beispiel funzt im Grunde:
    Hier das Gsämml (XAML):
    Spoiler anzeigen

    XML-Quellcode

    1. <Window x:Class="MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. Title="MainWindow" Height="350" Width="525">
    5. <Grid>
    6. <Button Content="{Binding Path=Text}" Name="Btn1" Click="Umschalten" />
    7. </Grid>
    8. </Window>

    Die zugehörige Window-Klasse:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Class MainWindow
    2. Public Sub New()
    3. ' Dieser Aufruf ist für den Designer erforderlich.
    4. InitializeComponent()
    5. ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
    6. MyProp.Text = "Start"
    7. Me.DataContext = MyProp 'Hier der Datacontext für die Form
    8. Me.Title = MyProp.Text 'Zum Test
    9. End Sub
    10. Dim Flacker As Boolean
    11. Property MyProp As New Props
    12. Private Sub Umschalten(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
    13. Flacker = Not Flacker
    14. MyProp.Text = "b = " & Flacker.ToString 'Umschalten der gebundenen Content-Eigenschaft des Button
    15. Me.Title = MyProp.Text 'Zum Test
    16. End Sub
    17. End Class

    und die Klasse mit der Property:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Public Class Props
    3. Implements INotifyPropertyChanged
    4. Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    5. Private _text As String
    6. Public Property Text As String
    7. Get
    8. Return _text
    9. End Get
    10. Set(ByVal value As String)
    11. If value <> _text Then
    12. _text = value
    13. OnPropertyChanged("Text")
    14. End If
    15. End Set
    16. End Property
    17. Protected Sub OnPropertyChanged(ByVal name As String)
    18. RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
    19. End Sub
    20. End Class

    Hier ist der DataContext vom VB-Code aus festgelegt. Geht das nicht normalerweise auch vom XMAL-Code aus als <Window.Resources oder so? Diese Deklarationen vor allem im Kopf des XAML versteh ich immer nicht. Da gibts in Beispielen dann Verweise mit XMLS:c="xxxx" oder XMLS:x="xxxx" und solch Zeugs. Ich hab da schon mal eine Klasse dran knoten können, aber ich will doch die Instanz der Klasse als Quelle haben (also ein Objekt ?(

    Kann mich da mal bitte jemand aufklären?

    Fielen Dank

    Vatter
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    Moinsen Vatter,

    ich versteh nicht ganz wo du die Property befüllst.
    ich kenn das nur so:

    XML-Quellcode

    1. <GridView>
    2. <GridViewColumn Header="Kundenname"
    3. DisplayMemberBinding="{Binding Path=kundenname}"
    4. Width="100"/>


    und um auf die Binding zugreifen zu müssen, habe ich diese selber geschrieben.

    VB.NET-Quellcode

    1. Private Sub dgvbindings()
    2. Dim kundenspalte As New GridViewColumn
    3. Dim projektspalte As New GridViewColumn
    4. Dim dauerspalte As New GridViewColumn
    5. Dim bearbeiterspalte As New GridViewColumn
    6. kundenspalte.DisplayMemberBinding = New Binding("kundenname")
    7. projektspalte.DisplayMemberBinding = New Binding("projektname")
    8. dauerspalte.DisplayMemberBinding = New Binding("dauer")
    9. bearbeiterspalte.DisplayMemberBinding = New Binding("bearbeiter")
    10. kundenspalte.Header = "Kundenname"
    11. projektspalte.Header = "Projektname"
    12. dauerspalte.Header = "Dauer"
    13. bearbeiterspalte.Header = "Bearbeiter"
    14. End Sub


    dadurch kann ich dann per Binding Path:kundenname
    meine Befüllung (die noch nicht vertig ist) abrufen.

    Grüßle Marco
    Ich finde ganz wesentlich, den DataContext im Window-Xaml festzulegen.
    dieses Xmls-Zeugs kapiere ich auch nicht.
    Und da kommt ja noch das Bekanntmachen eigener Verweise hinzu: Das verstehe ich zwar prinzipiell, nur nicht, warum das sone bescheuerte Syntax sein muß.
    Also wenn die mich gefragt hätten - ich hätte etwas einfacheres empfohlen ;)
    WpfTreeview-Tut
    auch die weiterführenden Links beachten: Wpf ist MVVM, und das bedeutet: CodeBehind ist Design-Fehler.
    Wpf lernen
    4ViewsWpf
    wpftutorial.net/LearnWPFin14Days.html (der hat sich nur verschrieben: er meint: Learning in 2 Years)

    Inzwischen bevorzuge ich übrigens, das Root-ViewModel als Resource in die App.Xaml zu packen, und den DataContext eines Fensters nicht an statische Felder zu binden, sondern an diese Root-Source. Vorteil: Unterstützung der Binding-Auswahl per Designer - vermeidung von Binding-Mismatches

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

    Moin MarcoIT,
    ich hab da nur mal ein gaaanz einfaches Beispiel testen wollen. da wird nicht viel befüllt. Es geht einfach darum, das der Txt des Button durch die Klasse Props über das Bining verändert wird, um die Mechanik zu verstehen. Dabei fiel mir eben auf, dass das Binding im Code (ist das der CodeBehind? (blöde Frage oder?)) erfolgt. Wenn man mit typisiertem Dataset rumexperimentiert, werden die Bindungen im Xaml festgelegt. Und das ist schließlich auch ein lokales Objekt der Dataset-Klasse.

    Hallo EDR,
    deine Supertuts mit WPFTreeview und die darin verlinkten hab ich schon gelesen und versucht zu vertehen. Leider bin ich längst mit meinem Verständnis noch nicht an der Stelle wo du ansetzt...
    Auch das MVVM ist mir noch etwas schleierhaft.

    Jetzt habich mal das hier aus deinem Code rausverkopiert:

    XML-Quellcode

    1. <Window x:Class="MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. Title="MainWindow" Height="350" Width="525"
    5. xmlns:my="clr-namespace:WpfApp2"
    6. DataContext="{x:Static my:MainWindow.MyProp}">
    Die letzten beiden Zeilen führen zu meiner gewünschten Property. Das funzt aber nur mit Shared Property oder gibs statt static noch nen anderes Argument?
    Ich muß mir mal dein Projekt ruinterziehen, das mit mainModel und Co blick ich so nich... :|
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:

    ErfinderDesRades schrieb:

    http://www.wpftutorial.net/LearnWPFin14Days.html (der hat sich nur verschrieben: er meint: Learning in 2 Years)

    Wenn mans auf anhieb versteht (was imho nichtnicht so schwierig ist), ist es schon möglich mehr als die Grundlagen in einer Woche zu lernen....
    Hi!
    Ich würde es so machen.

    XML-Quellcode

    1. <Window x:Class="MainWindow"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. Title="MainWindow" Height="350" Width="525"
    5. xmlns:my="clr-namespace:WpfApp2">
    6. <Grid>
    7. <Grid.DataContext>
    8. <my:Props/>
    9. </Grid.DataContext>
    10. <Button Content="{Binding Path=Text}" Name="Btn1" Click="Umschalten" />
    11. </Grid>
    12. </Window>

    Nicht getestet!
    MfG
    hlghyr
    @hlghyr,

    XML-Quellcode

    1. <Grid.DataContext>
    2. <my:Props/>
    3. </Grid.DataContext>

    Das verweist doch aber auf die Klasse Props und nicht auf die Instanz derselben mit Namen MyProp. 8| ...
    ...teste grad...
    Geht wohl genau aus dem Grunde so nicht.

    Ich denk, ich schnall langsam EDR sein Aufbau. Werd da mal weiter mit rummachen :D
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    Das mit dem Context fürs Grid ist prinzipiell auch ok und sauber.

    XML-Quellcode

    1. <my:Props/>

    ist ein Objekt der Klasse Props, und an deren Properties kann gebunden werden.
    haken an der Sache ist, dass das Grid damit ein eigenes Props - Objekt als Datacontext hat, und wenn du ein zweites Form, oder UserControl hast, was auch an MyProps binden soll, dann haste 2 MyPropse, und stehst genauso auffm Schlauch, wie annodazumal, als man in WinForms mit mehreren Dataset-Instanzen unterwegs war.

    Wie gesagt, meine derzeitige Lieblings-Figur ist:

    XML-Quellcode

    1. <Application x:Class="SchrullenApp"
    2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4. StartupUri="Schrullen\Views\MainWindow.xaml"
    5. xmlns:my="clr-namespace:Schrullen"
    6. >
    7. <Application.Resources>
    8. <my:MainModel x:Key="Root"/>
    9. <!--
    10. ...
    11. -->
    12. </Application.Resources>
    13. </Application>
    14. <--und dann-->
    15. <Window x:Class="Schrullen.MainWindow"
    16. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    17. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    18. xmlns:hlp="clr-namespace:System.Windows.Controls"
    19. Title="MainWindow" Height="350" Width="525"
    20. xmlns:my="clr-namespace:Schrullen"
    21. DataContext="{StaticResource Root}"
    22. >
    23. <!--
    24. ...
    25. -->
    Auf diese Weise können viele Fenster ans selbe Viewmodel gehängt werden

    ErfinderDesRades schrieb:

    haken an der Sache ist, dass das Grid damit ein eigenes Props - Objekt als Datacontext hat,

    Aahhh, also bezieht sich diese Binding nicht auf das von mir im VB erzeugte Objekt sondern Gsämml legt sich ein eigenes an. Dann ist auch klar, warum meine Änderungen an meinem Objekt keine Auswirkungen auf die Anzeige hatten.
    Und du erzeugst bei dir 1 Instanz deiner Mainmodel-Klasse und greifst ausschließlich auf diese Instanz zu? Das ist ja dann ähnlich wie deine DB-Extensions mit dem projektweiten Dataset.
    Ich beginne zu ahnen, auf was das hinausläuft...

    Danke dir EDR

    Edit:
    nach stundenlanger Spielerei hab ich jetzt festgestellt, dass deine Lieblings-Figur genial ist. Es muß dann allerdings der Konstruktor der MainModel-Klasse auf Public gestellt werden. Aber dann gehts hervorragend.
    Da verzichtest du bei dieser Konstellation allerdings auf die Designermöglichkeiten, ein DGV auf die Form zu zerren. Sonst gibbet ja wieder üfr jedes Windoof ne neue Dataset-Instanz. Richtig?
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:

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

    Vatter schrieb:

    Da verzichtest du bei dieser Konstellation allerdings auf die Designermöglichkeiten, ein DGV auf die Form zu zerren.

    weiß garnet, obs in Wpf noch das Datenfenster gibt.
    Stattdessen hat Datagrid bei den Properties einen Link "Spalten generieren" - dassis auch ganz gut.

    Dataset kommt in Wpf auch nicht mehr richtig mit, oder besser gesagt: Sie haben es ausgebootet.
    Weil Xaml kann keine verschachtelten Klassen darstellen, und typisierte DataRows sind aber verschachtelte Klassen.
    WEnnde dich mit DataTemplates beschäftigst, stellste fest, es gibt keine Möglichkeit im Xaml einem DataTemplate seinen Typ anzugeben - jdfs. ich hab da noch keine Lösung für gefunden.