Reputation: 681
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
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
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
Reputation: 3735
Try by changing this:
Text="{Binding Path=oTime.TimeUpdate}"
to:
Text="{Binding Path=oTime.TimeUpdate, UpdateSourceTrigger="PropertyChanged"}"
Upvotes: 0
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