【问题标题】:WP7 UIElement property bound to an ObservableCollection isn't updated when an item is added or removed from the ObservableCollection从 ObservableCollection 添加或删除项目时,绑定到 ObservableCollection 的 WP7 UIElement 属性不会更新
【发布时间】:2011-09-07 07:19:37
【问题描述】:

在以下代码中:绑定到 ObservableCollectionUIElement 在集合中添加或删除项目时不会更新。

具体来说:

一个 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 对象是 Person 对象的 ObservableCollection。 Links 对象是 Link 对象的 ObservableCollection:

 public class Links: ObservableCollection<Link>
    {

    }


    public class Crowd : ObservableCollection<Person>
    {

    }

WP7 应用程序的 MainPage 类是 PhoneApplicationPage 类的子类。 它包含两个属性: 人群,人群对象和 我,一个 Person 对象。

应该显示以下 XAML: a) 从 Me 对象到 Crowd 中的 Person 对象的链接数,以及 b) Crowd 中的 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)中添加或删除 Link 对象时,名为“LinkCounter”的文本块不会更新,即使它绑定到 ObservableCollection。

由于 Me.Links ObservableCollection 在添加新链接或从中删除现有链接时发生更改,因此我认为绑定到它的任何内容都应该更新。

对于这个问题的任何帮助将不胜感激。 谢谢。

【问题讨论】:

    标签: windows-phone-7 data-binding silverlight-4.0 observablecollection uielement


    【解决方案1】:

    这里不会触发数据绑定,因为您没有更改对 Links 集合的引用。而不是绑定到引用并使用转换器尝试使用

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

    【讨论】:

    • 该建议导致异常——(因为 Count 是一种方法?)。这就是我在原始代码中使用 Converter 的原因。
    • 附录。抱歉,在更改有关 DataContext 的另一行后,该建议有效。我猜这是因为在 Links 集合中添加或删除项目时,Links.Count 的值会发生变化。这是有道理的,但是文档说只要删除或添加项目就会触发 CollectionChanged 事件。为什么没有因此触发对 Me.Links 的引用。这是一个相关的问题,我想检查 Links 集合中的 Link 对象,只要它们的计数发生变化。我是否将链接作为参数传递给转换器?
    猜你喜欢
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多