Свойство WP7 UIElement, привязанное к ObservableCollection, не обновляется, когда элемент добавляется или удаляется из ObservableCollection - PullRequest
0 голосов
/ 07 сентября 2011

В следующем коде: 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 изменяется при добавлении новой ссылки или удалении существующей ссылки, я подумал, что все, что с ней связано, должно обновиться.

Любая помощь по этой проблеме будет принята с благодарностью.Спасибо.

1 Ответ

0 голосов
/ 07 сентября 2011

Привязка данных здесь не сработает, поскольку вы не меняете ссылку на коллекцию ссылок.Вместо привязки к ссылке и использования конвертера попробуйте использовать

<TextBlock x:Name=LinkCounter  Text="{Binding ElementName=ThePage, Path=Me.Links.Count" />
...