在以下代码中:绑定到ObservableCollection
时,绑定到ObservableCollection
的某个UIElement
在向项目添加或从集合中移除时不会更新。当向ObservableCollection添加或删除项目时,WP7 UIElement属性绑定到ObservableCollection时未更新
具体来说:
甲Person对象包括ObservableCollection
属性,链接,它可以包含任何数量的可指其它Person对象链接对象。 Person和Link类都实现了INotifyPropertyChanged
接口。
public class Person: INotifyPropertyChanged
{
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
// fields
private string id = "";
private string firstName = "";
private string lastName = "";
private Links links = new Links();
// properties firing PropertyChanged events
public string ID
{
get { return id; }
set
{
if (value != this.id)
{
this.id = value;
NotifyPropertyChanged("ID");
}
}
}
public string FirstName
{
get { return firstName; }
set
{
if (value != this.firstName)
{
this.firstName = value;
NotifyPropertyChanged("FirstName");
}
}
}
public string LastName
{
get { return lastName; }
set
{
if (value != this.lastName)
{
this.lastName = value;
NotifyPropertyChanged("LastName");
}
}
}
public Links Links
{
get { return links; }
set
{
if (value != this.links)
{
this.links = value;
NotifyPropertyChanged("Links");
}
}
}
// constructors
public Person()
{
new Person("", "", "");
}
public Person(string id, string firstName, string lastName)
{
this.ID = id;
this.FirstName = firstName;
this.LastName = lastName;
}
}
public enum LinkState { none, oneway, twoway }
public class Link: INotifyPropertyChanged
{
// INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
// fields
private Person fromWhom;
private Person toWhom;
// properties firing PropertyChanged events
public Person FromWhom
{
get { return fromWhom; }
set
{
if (value != this.fromWhom)
{
this.fromWhom = value;
NotifyPropertyChanged("FromWhom");
}
}
}
public Person ToWhom
{
get { return toWhom; }
set
{
if (value != this.toWhom)
{
this.toWhom = value;
NotifyPropertyChanged("ToWhom");
}
}
}
// constructors
public Link()
{
new Link(null, null);
}
public Link(Person fromWhom, Person toWhom)
{
this.FromWhom = fromWhom;
this.ToWhom = toWhom;
}
}
链接和人群类都是ObservableCollections的子类。 Crowd对象是Person对象的ObservableCollection。甲链接目的是链接对象的一个ObservableCollection:
public class Links: ObservableCollection<Link>
{
}
public class Crowd : ObservableCollection<Person>
{
}
MainPage类的WP7应用的是的PhoneApplicationPage类的子类。 它包含两个属性: Crowd,一个人群对象和 Me,一个Person对象。
以下XAML应该显示: a)从人物对象到人群中的链接数量,以及 b)人群中的人物对象列表。
<phone:PhoneApplicationPage
x:Name="ThePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PersonLink"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
x:Class="PersonLink.MainPage"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True"
DataContext="{Binding ElementName=ThePage, Path=Crowd}">
<phone:PhoneApplicationPage.Resources>
<local:LinksToCountConverter x:Key="linkCount" />
</phone:PhoneApplicationPage.Resources>
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ElementName=ThePage, Path=Me.FirstName}" />
<TextBlock Text=" has " />
<TextBlock x:Name=LinkCounter Text="{Binding ElementName=ThePage, Path=Me.Links,Converter={StaticResource linkCount}}" />
<TextBlock Text=" links." />
</StackPanel>
<ItemsControl ItemsSource="{Binding .}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ID}" />
<TextBlock Text=" " />
<TextBlock Text="{Binding FirstName}" />
<TextBlock Text=" " />
<TextBlock Text="{Binding LastName}" />
<local:LinkButton Content="Link" Click="LinkButton_Click"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</phone:PhoneApplicationPage>
然而,当链接对象中添加或Me.Links(一ObserverableCollection)的文本块名为“LinkCounter”删除不更新,即使它绑定到的ObservableCollection。
由于Me.Links ObservableCollection在添加新链接或更改现有链接时发生更改,因此我认为绑定到它的任何内容都应该更新。
在这个问题上的任何帮助,将不胜感激。 谢谢。
该建议会导致异常 - (因为计数是一种方法?)。这就是我在原代码中使用Converter的原因。 – Stackoverflower
附录。对不起,在更改关于DataContext的另一行后,该建议奏效了。我猜这是因为Links.Count的值在链接集合中添加或删除项目时发生更改。这很有道理,但文档说,每当删除或添加项目时都会触发一个CollectionChanged事件。为什么不引用Me.Links因此被触发。这里有一个相关的问题,我想在链接集合中的链接对象改变时进行检查。我是否将链接作为参数传递给转换器? – Stackoverflower