2017-04-07 33 views
0

我正在关注WPF数据绑定的教程。我想绑定到一个.NET对象的属性到一个XAML控件,但该控件不显示预期的数据。这是我所相信的是代码的有关章节:WPF绑定与.NET对象不通信数据

在程序代码:(注:去掉的ObservableCollection在图片集锦原帖后)

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 

在XAML(解决方案/项目名称为CH13-图片集锦):

<Window x:Class="PhotoGallery.MainWindow" 
    ... 
    xmlns:local="clr-namespace:Ch13_PhotoGallery.PhotoGallery" 
    ...> 

<Window.Resources> 
    <local:Photos x:Key="Photos"/> 
</Window.Resources> 

这是不显示的数据的控制,这是照片集合的大小:

<Label x:Name="numItemsLabel" Background="AliceBlue" FontSize="8" Content="{Binding Source={StaticResource Photos}, Path=Count}"/> 

当我输入< Label>时,Intellisense为Path属性弹出'Count',所以我认为这告诉我我已经正确定义了一切。

如果我此行的程序代码添加到后面的刷新()方法:

numItemsLabel.Content = photos.Count 

然后,计数被正确显示。

但我没有得到在XAML绑定显示Photos.Count。

+0

是'photos'相同的对象'<本地:照片x:键=“照片”/>'? – ASh

+0

是的,我认为我的所有大写都一致,但是您的问题使我注意到我在MainWindow类中声明了'照片'未使用大写。所以我将它改为“照片”,但这似乎没有什么区别。 – Alan

+0

“是的,它是” - 不,它不是。这是一个完全不同的对象。你在做什么来填充作为资源创建的'Photos'实例?您是否知道您正在创建两个完全不同的'Photos'实例,或者您认为框架中的某些内容会以某种方式关联这两个? –

回答

1

这就造成了Photos类的新实例

<local:Photos x:Key="Photos"/> 

如果你想绑定到您已在MainWindow.xaml.vb文件中创建的Photos收集你应将其公开为公共属性 - 您只能绑定到属性,但不能绑定字段 - 并将窗口的DataContext设置为c的一个实例其中,此属性的定义,即窗口类本身,你的情况姑娘:

Class MainWindow 
    Public Property Photos As Photos 

    Public Sub New() 

     ' This call is required by the designer. 
     InitializeComponent() 
     DataContext = Me 
     ... 
    End Sub 
End Class 

您可以将绑定直接的财产:

<Label x:Name="numItemsLabel" Background="AliceBlue" FontSize="8" Content="{Binding Path=Photos.Count}"/> 
1

您的视图模型需要实现INotifyPropertyChanged接口,这会让你的窗口倾听更改您的视图模型

这里有一个如何在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

视图模型

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代码隐藏

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 
+0

编写一个ViewModel需要我一点时间,我会这样做。但是,我正在使用的教程不使用此项目的ViewModel。但我相信你正在用INotifyPropertyChanged指引我正确的方向。在本教程中提到了这一点,但在本练习中未绑定到.NET对象。如果我不使用ViewModel,从哪里可以放置INotifyPropertyChanged?此外,我搜索完成的解决方案,并没有在该项目中找到INotifyPropertyChanged。显然,我无法从解决方案中解读我的问题。 – Alan

+0

@Alan我会采取萨尔瓦多的建议,只是写一个视图模型。从他的例子中可以看出,这不是一项大量的工作。从多年的WPF经验来看,任何不以创建视图模型开始的教程都是毫无价值的。 –

+0

会做。为了记录,这篇特别的教程不专注于项目体系结构,而是关注WPF操作的细节。 – Alan