WPF binding to a .NET object that does not pass data
I am following WPF data binding tutorial. I am trying to bind a .NET property to a XAML control, but the control is not displaying the expected data. Here are what I consider to be the relevant sections of code:
To procedural code: (Note: removed ObservableCollection in PhotoGallery after original post)
Namespace PhotoGallery
Partial Public Class MainWindow
Inherits Window
Private photos As New Photos
...
End Class
Namespace PhotoGallery
Public Class Photos
Inherits Collection(Of Photo)
...
End Class
In XAML (solution / project name - Ch13-PhotoGallery):
<Window x:Class="PhotoGallery.MainWindow"
...
xmlns:local="clr-namespace:Ch13_PhotoGallery.PhotoGallery"
...>
<Window.Resources>
<local:Photos x:Key="Photos"/>
</Window.Resources>
And this is a control that does not display data that is the size of the Photos collection:
<Label x:Name="numItemsLabel" Background="AliceBlue" FontSize="8" Content="{Binding Source={StaticResource Photos}, Path=Count}"/>
When I typed in <Label>, Intellisense brought up "Count" for the Path property, so I think this tells me that I have defined everything correctly.
If I add this line of procedural code to the refresh () method:
numItemsLabel.Content = photos.Count
Then the counter is displayed correctly.
But I am not getting the binding in XAML to display Photos.Count.
source to share
This creates a new instance of the class Photos
:
<local:Photos x:Key="Photos"/>
If you want to bind to a collection Photos
that you created in your MainWindow.xaml.vb
file, you must open it as a public property - you can only bind to properties, not fields - and set the DataContext
window to an instance of the class in which the property is defined, i.e. e. the window class itself in your case:
Class MainWindow
Public Property Photos As Photos
Public Sub New()
' This call is required by the designer.
InitializeComponent()
DataContext = Me
...
End Sub
End Class
You can bind directly to a property:
<Label x:Name="numItemsLabel" Background="AliceBlue" FontSize="8" Content="{Binding Path=Photos.Count}"/>
source to share
Your ViewModel needs to implement INotifyPropertyChanged , this will allow your window to listen for changes to your ViewModel
Here is an example of how to implement this interface in VB https://social.msdn.microsoft.com/Forums/vstudio/en-US/7de44362-8b88-4292-b4ee-0385c3b34d7d/im-just-looking-for-a- simple-vb-net-mvvm-sample-wpf? forum = wpf
ViewModel
Public Class ViewModel
Implements INotifyPropertyChanged
Public Sub New()
Me.myTextValue = "default value..."
End Sub
Private myTextValue As String = String.Empty
Public Property MyTextProperty() As String
Get
Return Me.myTextValue
End Get
Set(ByVal value As String)
Me.myTextValue = value
NotifyPropertyChanged("MyTextProperty")
End Set
End Property
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(ByVal propertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
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>
<TextBox Text="{Binding MyTextProperty}"/>
</Grid>
</Window>
XAML for
Class MainWindow
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.DataContext = New ViewModel()
End Sub
End Class
source to share