В следующем коде: UIElement
, связанный с ObservableCollection
, не обновляется, когда элементы добавляются или удаляются из коллекции.
В частности:
Объект Person включает в себяObservableCollection
свойство Links, которое может содержать любое количество объектов Link, которые могут ссылаться на другие объекты 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;
}
}
Классы Links и Crowd являются подклассами ObservableCollections.Объект Crowd является ObservableCollection объектов Person.Объект Links представляет собой ObservableCollection объектов Link:
public class Links: ObservableCollection<Link>
{
}
public class Crowd : ObservableCollection<Person>
{
}
Класс MainPage приложения WP7 является подклассом класса PhoneApplicationPage.Он содержит два свойства: Crowd, объект Crowd и Me, объект Person.
Предполагается, что должен отображаться следующий XAML: a) Число ссылок от объекта Me на объекты Person в толпе иб) Список объектов Person в толпе.
<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 изменяется при добавлении новой ссылки или удалении существующей ссылки, я подумал, что все, что с ней связано, должно обновиться.
Любая помощь по этой проблеме будет принята с благодарностью.Спасибо.