tags:

views:

35

answers:

1

I am quite new to WPF and I am confused about how Data Bindings should behave.

I have created a class that has 1 property ("status") and three methods that are responsible for changing the status. This class implements the INotifyPropertyChanged interface so that I am able to notify the calling code when the Status changes.

The class looks like this:

Public Class StreetLight
    Implements System.ComponentModel.INotifyPropertyChanged
    Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

    Private _status As String
    Public Property Status As String
        Get
            Return _status
        End Get
        Set(ByVal value As String)
            _status = value
            RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("Satus"))
        End Set
    End Property
    Public Sub New()
        _status = "unknown"
    End Sub
    Public Sub Red()
        Status = "Red"
    End Sub
    Public Sub Yellow()
        Status = "Yellow"
    End Sub
    Public Sub Green()
        Status = "Green"
    End Sub
End Class

I have created a WPF User Control to represent this class. This User Control is bound to an instance the StreetLight class. It displays the status of the StreetLight and allows the user to change the status using buttons:

<UserControl x:Class="StreetLightUC"
             x:Name="StreetLightUC"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:twpf="clr-namespace:TryingWPF"
             mc:Ignorable="d" 
             d:DesignHeight="30" d:DesignWidth="360">
    <UserControl.Resources>
        <twpf:StreetLight x:Key="theLight" PropertyChanged="theLight_PropertyChanged" />
    </UserControl.Resources>
    <StackPanel x:Name="StreetLightContent" Orientation="Horizontal">
        <Label Width="100" HorizontalAlignment="Left">Street Light _Status</Label>
        <Label x:Name="streetLightValue" Width="120" HorizontalAlignment="Right" Content="{Binding Path=Status, Mode=OneWay}"></Label>
        <Button x:Name="Red" Click="TurnRed" Width="60">Turn Red</Button>
        <Button x:Name="Green" Click="TurnGreen" Width="60">Turn Green</Button>
    </StackPanel>
</UserControl>

My problem is that even when the status is changed for theLight, it is not updated in the Label that is bound to the Status property unless I create a new StreetLight and set the DataContext to this new instance in the "StreetLight_PropertyChanged" event that handles the PropertyChagned event for the "theLight"

Like so:

Public Class StreetLightUC
    Public Sub New()
        InitializeComponent()
    End Sub
    Private Sub TurnRed(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        Dim light As StreetLight= CType(FindResource("theLight"), StreetLight)
        light.Red()
    End Sub

    Private Sub TurnGreen(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        Dim light As StreetLight = CType(FindResource("theLight"), StreetLight)
        light.Unlock()
    End Sub

    Private Sub theLight_PropertyChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs)
        Dim light As StreetLight = CType(sender, StreetLight )
        Dim newLight As New StreetLight
        newLight.Status = light.Status
        StreetLightContent.DataContext = newLight
    End Sub
End Class

Am I doing something wrong? It doesn't seem like I should have to create a new instance of the class to display the updated status-property when this property is change....

Thanks,

-Frinny

+2  A: 

You have a typo ("Satus" instead of "Status"):

RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("Satus"))

Should be:

RaiseEvent PropertyChanged(Me, New System.ComponentModel.PropertyChangedEventArgs("Status"))

With this typo, the binding doesn't see that "Status" has changed, and never updates. If you correct this, the PropertyChanged event will correctly reflect that "Status" has changed.

Reed Copsey
Thank you for your reply. I thought the problem was due to my lack of knowledge on data binding...and I didn't notice the type-o.
Frinavale