绑定到DataContext中的项目计数

时间:2010-05-26 20:33:58

标签: wpf binding

我想绑定到DataContext中的Count / item数量。

我有一个对象,让我说一个有List<address>作为属性的人。我想显示该人的地址数量,即:5或6或任何情况。

我已尝试过{Binding Path=address#.Count}和其他一些人,但似乎没有效果。

任何帮助都将不胜感激,谢谢。

5 个答案:

答案 0 :(得分:28)

您需要绑定属性的名称,而不是其类型。

C#:

public class Person
{
    ...
    public List<address> Addresses { get; set; }
    ...
}

XAML:

{Binding Addresses.Count}

假设您的DataContextPerson类型的对象。

答案 1 :(得分:18)

正如tehMick所说,您可以使用路径Addresses.Count进行绑定。

但请注意,除非AddressesObservableCollection<address>或其他类型实现INotifyCollectionChanged,否则添加和删除地址不会影响用户界面中显示的数字它的初始显示。如果需要,您需要在视图模型中更改集合的类型(这是最简单的),或者在视图模型中实现公开计数的属性,并在每次提升PropertyChanged事件时添加或删除地址。

修改

我喜欢读一个答案,想着,“嘿,那不对,”然后意识到我写了它。

如果绑定到 实现INotifyCollectionChanged的对象,则在集合中添加或删除项目时,UI中的计数不会更改。当INotifyPropertyChanged属性发生更改时, 对象必须实现PropertyChanged并引发Count

幸运的是,ObservableCollection<T>确实如此。所以我的答案不是 错误。

答案 2 :(得分:3)

XAML:

<Window x:Class="CountDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="CountDemo" Height="300" Width="300">
    <StackPanel>
        <TextBlock Text="{Binding Path=Addresses.Count}" />
    </StackPanel>
</Window>

代码背后:

using System.Collections.Generic;
using System.Windows;

namespace CountDemo
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            DataContext = new Person();
        }
    }

    public class Person
    {
        public List<Address> Addresses
        {
            get { return new List<Address>() {new Address(), new Address(), new Address()}; }
        }
    }

    public class Address
    {
    }
}

答案 3 :(得分:1)

使用功能示例代码扩展tehMick's答案:

<强> XAML:

<Window x:Class="Sandbox.Wpf.PropertyCount.PropertyCount"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Property Count" Height="300" Width="300">
    <StackPanel>
        <ListView ItemsSource="{Binding Path=People}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Grid Margin="4">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding Path=Name}" Margin="3" />
                        <TextBlock Grid.Column="1" Margin="3">
                            <TextBlock Text="{Binding Path=Addresses.Count}" /> <Run>addresses</Run>
                        </TextBlock>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackPanel>
</Window>

代码背后:

namespace Sandbox.Wpf.PropertyCount
{
    /// <summary>
    /// Interaction logic for PropertyCount.xaml
    /// </summary>
    public partial class PropertyCount : Window
    {

        public PropertyCount()
        {
            InitializeComponent();
            this.DataContext = new Model();
        }
    }

    public class Model
    {
        public List<Person> People { get; private set; }

        public Model()
        {

            People = new List<Person>{
                new Person ("joe", new List<object> { 1, 2, 3 }),
                new Person ("bob", new List<object> { 1, 2 }),
                new Person ("kay", new List<object> { 1, 2, 3, 4, 5 }),
                new Person ("jill", new List<object> { 1, 2, 3, 4 }),
            };
        }
    }

    public class Person
    {
        public string Name { get; set; }
        public List<object> Addresses { get; set; }

        public Person(string name, List<object> addresses)
        {
            Name = name;
            Addresses = addresses;
        }
    }

}

答案 4 :(得分:0)

就我而言,罗伯特的回答让我非常接近我所追求的目标。但是,我正在从服务调用中向列表中添加许多项目,并且不希望为每个项目触发事件。为此,我利用了BindingList中已构建的功能:

public class BindingListNotifyCount<T> : BindingList<T>, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected override void OnListChanged(ListChangedEventArgs e)
    {
        base.OnListChanged(e);
        RaisePropertyChanged("Count");
    }

    protected void RaisePropertyChanged([CallerMemberName]string propertyName = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

然后我只是用它作为:

displayItems.RaiseListChangedEvents = false;
serviceItems.ForEach(item => displayItems.Add(item));
displayItems.RaiseListChangedEvents = true;
displayItems.ResetBindings();