SDanks
SDanks

Reputation: 681

WPF Trouble Updating a Textbox from a variable

Using WPF, and VB.net, I want to update a textbox in a textblock with the current date and time. I use a timer, and it seems to be firing, and setting an object property to "Now". And I am using iNotifyPropertyChanged.

All I get is an empty textbox with no data in it. Can you help? Maybe my context is off?

XAML

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
    <TextBlock DataContext="oTime"> 
        <TextBox x:Name="myTextBox" 
                 Width="200" Height="50" Foreground="Black" 
                 Text="{Binding Path=oTime.TimeUpdate}"></TextBox>
    </TextBlock>
</Grid>
</Window>

VB Code

Imports System.ComponentModel
Imports System.Windows.Threading

Class MainWindow
  Public oTime As TimeUpdate = New TimeUpdate
  Private dpTimer As DispatcherTimer

  Private Sub TextBlock_SourceUpdated(ByVal sender As System.Object, ByVal e As System.Windows.Data.DataTransferEventArgs)

  End Sub

  Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
      dpTimer = New DispatcherTimer
      dpTimer.Interval = TimeSpan.FromMilliseconds(1000)
      AddHandler dpTimer.Tick, AddressOf TickMe
      dpTimer.Start()
  End Sub

  Private Sub TickMe()
      oTime.TimeUpdate = Now.ToString
      Debug.Print(oTime.TimeUpdate)
  End Sub

End Class

Public Class TimeUpdate
Implements INotifyPropertyChanged

  Private sTime As String

  'Declare the Event
  Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged

  Public Property TimeUpdate() As String
      Get
          Return sTime

      End Get
      Set(ByVal value As String)
          sTime = value
          'Call onPropertyChanged whenever the property is updated
          OnPropertyChanged("TimeUpdate")
      End Set

  End Property

  Protected Sub OnPropertyChanged(ByVal name As String)
      RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
  End Sub

End Class

Upvotes: 0

Views: 4424

Answers (4)

ShadeOfGrey
ShadeOfGrey

Reputation: 1266

Few things seem to be missing. First the DataContext of the window is not set. You can do it the constructor:

Public Sub New()
    DataContext = oTime
End Sub

This allows your view to see the contents of the TimeUpdate class.

And then change you XAML (bind directly to the TimeUpdate property):

<Grid> 
    <TextBox x:Name="myTextBox" 
             Width="200" Height="50" Foreground="Black" 
             Text="{Binding Path=TimeUpdate}"></TextBox>
</Grid>

Update: Alternative way will be to add the DataContext line in the Window tag. This way your MainWindow class becomes visible to the view and you can bind to the public properties.

<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="350" Width="525">

Now create a public property to access the object:

Public Property OTime() As TimeUpdate
    Get
        Return oTime
    End Get
    Set
        oTime = value
    End Set
End Property

And bind the textbox to it:

<Grid> 
    <TextBox x:Name="myTextBox" 
             Width="200" Height="50" Foreground="Black" 
             Text="{Binding Path=OTime.TimeUpdate}"></TextBox>
</Grid>

Upvotes: 5

Dean Chalk
Dean Chalk

Reputation: 20471

try changing this

OnPropertyChanged("TimeUpdate")

to this

OnPropertyChanged("oTime")

Also, make sure you have set your DataContext on your root grid

<Grid DataContext="{Binding RelativeSource={RelativeSource Mode=Self}, Path=.}">

Upvotes: -1

Ali Adlavaran
Ali Adlavaran

Reputation: 3735

Try by changing this:

 Text="{Binding Path=oTime.TimeUpdate}"

to:

 Text="{Binding Path=oTime.TimeUpdate, UpdateSourceTrigger="PropertyChanged"}"

Upvotes: 0

Hoang Dang
Hoang Dang

Reputation: 298

I think your data context is off. Correctly me if I am wrong but it looks like you're setting it to a string value rather than an object. Is oTime an object you have created in the XAML as a resource? If so you will need to get it with the StaticResource. Otherwise you will need to instantiate.

Eg.

<TextBlock >
    <TextBlock.DataContext>
        <!-- This will instantiate the object-->
        <local:TimeUpdate/> 
    </TextBlock.DataContext>
     <TextBox x:Name="myTextBox" Width="200" Height="50" Foreground="Black" Text="{Binding Path=TimeUpdate}"></TextBox>
</TextBlock>

Edit: I just noticed that you have a TimeUpdate object instantiated in the MainWindow class. In that case I would set the DataContext of the Window to itself in the code behind and make oTime a property. That way you don't have to set the DataContext for the TextBlock. It would use the parent's DataContext, in this case the Window. You XAML would now look like below:

<TextBlock>
     <TextBox x:Name="myTextBox" Width="200" Height="50" Foreground="Black" Text="{Binding Path=oTime.TimeUpdate}"/>
</TextBlock>

Upvotes: 0

Related Questions