TextBlock an Property einer Klasse binden.

  • WPF

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von Jeiss.

    TextBlock an Property einer Klasse binden.

    Hallo,
    ich verzweifle so langsam an der doch recht einfachen Aufgabe ein TextBlock an eine Eigenschaft (Property) einer Klasse zu binden.
    Bei meinem Testprojekt handelt es sich um ein Visual Studio 2015 Projekt.
    Ich erlaube mir mal meinen Code hier zu posten, in der Hoffnung dass jemand den Fehler findet.
    Hier die Klasse:

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Public Class MyTestClass
    3. Implements INotifyPropertyChanged
    4. Private customerNameValue As String ' = "EMPTY"
    5. 'Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
    6. 'Private Sub NotifyPropertyChanged(ByVal info As String)
    7. ' RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
    8. 'End Sub
    9. Public Property CustomerName() As String
    10. Get
    11. Return Me.customerNameValue
    12. End Get
    13. Set(ByVal value As String)
    14. If Not (value = customerNameValue) Then
    15. Me.customerNameValue = value
    16. 'NotifyPropertyChanged("CustomerName")
    17. OnPropertyChanged("CustomerName")
    18. End If
    19. End Set
    20. End Property
    21. Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    22. Private Sub OnPropertyChanged(ByVal prop As String)
    23. RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(prop))
    24. End Sub
    25. End Class


    Mainwindow xaml:

    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. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. xmlns:local="clr-namespace:Notification_Test"
    7. mc:Ignorable="d"
    8. Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    9. <!--<Window.Resources>
    10. <local:MyTestClass x:Key="whyareyounotworking" />
    11. </Window.Resources>-->
    12. <Window.DataContext>
    13. <local:MyTestClass />
    14. </Window.DataContext>
    15. <Grid>
    16. <!--<Grid.DataContext>
    17. <local:MyTestClass />
    18. </Grid.DataContext>-->
    19. <Border><!--DataContext="whyareyounotworking"-->
    20. <TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="55,35,0,0" TextWrapping="Wrap" Width="80" Background="Coral" VerticalAlignment="Top"
    21. Text="{Binding CustomerName}">
    22. </TextBlock>
    23. </Border>
    24. <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="55,150,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="145" />
    25. <Button x:Name="button" Content="Go" HorizontalAlignment="Left" Margin="245,154,0,0" VerticalAlignment="Top" Width="75" />
    26. </Grid>
    27. </Window>


    Mainwindow Code benind:

    VB.NET-Quellcode

    1. lass MainWindow
    2. Public MyTest As MyTestClass
    3. Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
    4. MyTest = New MyTestClass
    5. End Sub
    6. Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
    7. MyTest.CustomerName = textBox.Text
    8. End Sub
    9. End Class

    Wie man an den aus kommentierten Zeilen erkennen kann hab ich schon so manches probiert. Leider ohne Erfolg....
    So, jetzt kann ich nur hoffen, dass ihr so früh am Samstagmorgen schon fit für dies Aufgabe seid.... ;)

    Vielen Dank im Voraus,
    Jeiss
    Du verwendet 2 Instanzen deiner MyTestClass:
    Einmal legt du eine davon im XAML Designer (Window.DataContext) an und das zweite mal im Codebehind.
    Beim Button Klick änderst du den Customer Name der Instanz im Codebehind. Gebunden wird aber an die welche du in XAML hinterlegt hast du somit siehst du keine Änderung.

    Setze entweder den DataContext im Codebehind oder verwende es gleich ganz korrekt und verwende für das ButtonClick ein Command welches im Viewmodel die Eigenschaft des CustomerName ändert.

    Suche dazu im Internet ein wenig nach MVVM (ModelViewViewModel) Pattern welches genau solche Fälle abdeckt.

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Hallo fichz,
    danke dass du mich nicht sitzen lässt.
    Ich hab deinen Vorschlag mal umgesetzt, zwar noch nicht ganz 100% korrekt mit einem Command und so. Wollte den Code so übersichtlich wie möglich halten. Erst mal sehen ob die Änderungen der Eigenschaft bis an den Textblock durchdringen, dann kann ich den Code immer noch "verfeinern".
    Mein XAML Code sieht jetzt folgendermaßen aus:

    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. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    6. xmlns:local="clr-namespace:Notification_Test"
    7. mc:Ignorable="d"
    8. Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    9. <Window.Resources>
    10. <local:MyTestClass x:Key="whyareyounotworking" />
    11. </Window.Resources>
    12. <Grid>
    13. <Border DataContext="whyareyounotworking"><!--DataContext="whyareyounotworking"-->
    14. <TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="55,35,0,0" TextWrapping="Wrap" Width="80" Background="Coral" VerticalAlignment="Top"
    15. Text="{Binding CustomerName}">
    16. </TextBlock>
    17. </Border>
    18. <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="55,150,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="145" />
    19. <Button x:Name="button" Content="Go" HorizontalAlignment="Left" Margin="245,154,0,0" VerticalAlignment="Top" Width="75" />
    20. </Grid>
    21. </Window>

    Und mein Code behind so:

    VB.NET-Quellcode

    1. Class MainWindow
    2. Public MyTest As MyTestClass
    3. Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
    4. MyTest = New MyTestClass
    5. End Sub
    6. Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
    7. MyTest.CustomerName = textBox.Text
    8. End Sub
    9. End Class

    An der TestKlasse ist immer noch alles gleich.
    Aber leider funktioniert es aber immer noch nicht.
    Hast du vielleicht noch eine Idee was geändert werden müsste?
    Vielen Dank im Voraus,
    Jeiss

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

    Hier mal ein kleines Beispiel für eine MVVM Architektur:
    Spoiler anzeigen
    ViewModel:

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Imports GalaSoft.MvvmLight.CommandWpf
    3. Public Class MainViewModel
    4. Implements INotifyPropertyChanged
    5. Private customerNameValue As String ' = "EMPTY"
    6. Public Property CustomerName() As String
    7. Get
    8. Return Me.customerNameValue
    9. End Get
    10. Set(ByVal value As String)
    11. If Not (value = customerNameValue) Then
    12. Me.customerNameValue = value
    13. OnPropertyChanged("CustomerName")
    14. End If
    15. End Set
    16. End Property
    17. Private _inputText As String ' = "EMPTY"
    18. Public Property InputText() As String
    19. Get
    20. Return Me._inputText
    21. End Get
    22. Set(ByVal value As String)
    23. If Not (value = _inputText) Then
    24. Me._inputText = value
    25. OnPropertyChanged("InputText")
    26. End If
    27. End Set
    28. End Property
    29. Private _changeTextCommand As ICommand
    30. Public ReadOnly Property ChangeTextCommand As ICommand
    31. Get
    32. Return _changeTextCommand
    33. End Get
    34. End Property
    35. Public Sub New()
    36. _changeTextCommand = New RelayCommand(Sub() CustomerName = InputText)
    37. End Sub
    38. Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    39. Private Sub OnPropertyChanged(ByVal prop As String)
    40. RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(prop))
    41. End Sub
    42. End Class


    Spoiler anzeigen
    Xaml:

    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. xmlns:local="clr-namespace:WpfApplication1"
    5. Title="MainWindow" Height="350" Width="525">
    6. <Window.DataContext>
    7. <local:MainViewModel x:Name="vm" />
    8. </Window.DataContext>
    9. <Grid>
    10. <Border>
    11. <TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="55,35,0,0" TextWrapping="Wrap" Width="80" Background="Coral" VerticalAlignment="Top"
    12. Text="{Binding CustomerName}">
    13. </TextBlock>
    14. </Border>
    15. <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="55,150,0,0" TextWrapping="Wrap" Text="{Binding InputText}" VerticalAlignment="Top" Width="145" />
    16. <Button x:Name="button" Content="Go" HorizontalAlignment="Left" Margin="245,154,0,0" VerticalAlignment="Top" Width="75" Command="{Binding ChangeTextCommand}" />
    17. </Grid>
    18. </Window>


    Hier habe ich ein ViewModel erstellt, welches die Daten für das View bereitstellt. An dieses (und nur dieses - kein Codebehind für die Daten) wird der DataContext gesetzt.
    Das Command übernimmt im Prinzip die Aufgabe für das Button_Click Event und bearbeitet die Daten innerhalb des Viewmodels. Aufgrund von Databinding wird dann die geänderte Eigenschaft im View wieder angezeigt
    (hab über nuget die Lib MVVMLight installiert für das RelayCommand).

    Sieh dir aber bitte dazu ein paar MVVM Beiträge im Internet an.
    msdn.microsoft.com/de-de/magazine/dd419663.aspx
    codeproject.com/articles/81929…p-basics-to-advance-level

    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    gHallo fichz,
    ​hatte leider noch keine Zeit dir auf deinen Beitrag zu antworten. Leider kann ich meinem Hobby nicht immer so oft nach gehen wie ich es gerne möchte. Geht aber wohl jedem so ;)
    ​Ja was soll ich noch sagen....deine Lösung funktioniert einwandfrei. Und schließlich ist das ja der Zweck der Übung. Auch wenn diese "professionelle" Vorgehensweise mir als hobby Programmierer irgendwie zu "Aufwendig" erscheint.
    ​Aber werde trotzdem versuchen mich mit diesem MVVM zu befreunden. Ich kann ja nicht verlangen, dass mir von Forenmitgliedern geholfen wird, wenn ich mir nicht mal die Mühe gebe selber etwas dazu zu lernen. Werde natürlich mit den von dir empfohlenen Links beginnen.
    ​Das mit der MVVM-Light Lib hat dank deiner Erklärung gleich auf Anhieb geklappt. Hatte ich mir viel komplizierter vorgestellt als ich dein Beitrag gelesen hab.
    ​Reicht das wenn ich deine Antwort als "Hilfreich" markiere (scheint mir nämlich untertrieben, war eher "sehr Hilfreich"), oder kann ich mich sonst noch auf irgend eine Weise bedanken.
    Diese Frage wäre damit also beantwortet und das Thema erfolgreich abgeschlossen.

    ​Danke,
    Jeiss