当从 ObservableCollection 添加或删除项目时,绑定到 ObservableCollection 的 WP7 UIElement 属性不会更新

发布于 2024-12-03 02:25:25 字数 7421 浏览 1 评论 0原文

在以下代码中:在集合中添加或删除项目时,绑定到 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 类的子类。 它包含两个属性: Crowd,一个 Crowd 对象和 我,一个 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”的 Textblock 不会更新,即使它绑定到 ObservableCollection。

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

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

In the following code: a UIElement bound to an ObservableCollection does not update when items are added or removed from the collection.

Specifically:

A Person object includes an ObservableCollection property, Links, which can contain any number of Link objects which can refer to other Person objects.
The Person and Link classes both implement the INotifyPropertyChanged interface.

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;
    }

}

The Links and Crowd classes are both subclasses of ObservableCollections. A Crowd object is an ObservableCollection of Person objects. A Links object is an ObservableCollection of Link objects:

 public class Links: ObservableCollection<Link>
    {

    }


    public class Crowd : ObservableCollection<Person>
    {

    }

The MainPage class of the WP7 application is a subclass of the PhoneApplicationPage class.
It contains two properties:
Crowd, a Crowd object and
Me, a Person object.

The following XAML is supposed to display:
a) The number of links from the Me object to the Person objects in the Crowd, and
b) A list of the Person objects in the Crowd.

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

HOWEVER, when Link objects are added or removed from Me.Links (an ObserverableCollection) the Textblock named "LinkCounter" doesn't update, even though its bound to the ObservableCollection.

Since the Me.Links ObservableCollection is changed when a new Link is added to it, or an existing Link is removed from, I thought that anything bound to it should update.

Any help on this problem would be greatly appreciated.
Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风筝在阴天搁浅。 2024-12-10 02:25:25

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

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

The databinding won't be triggered here as you are not changing the reference to the Links collection. Instead of binding to the reference and using a converter try using

<TextBlock x:Name=LinkCounter  Text="{Binding ElementName=ThePage, Path=Me.Links.Count" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文