wpf 绑定到 DataContext 中的项目数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2916564/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bind to Count of items in the DataContext
提问by Organ Grinding Monkey
I want to bind to the Count/amount of items within my DataContext.
我想绑定到我的 DataContext 中的项目数/数量。
I have an object, lets say person which has a List<address>
as a property. I would like to display the amount of addresses for that person ie: 5 or 6 or whatever the case may be.
我有一个对象,比如说有List<address>
一个属性的人。我想显示该人的地址数量,即:5 个或 6 个或其他任何情况。
I've tried {Binding Path=address#.Count}
and a few others but that doesnt seem to work.
我试过{Binding Path=address#.Count}
和其他一些,但这似乎不起作用。
Any help would be appreciated, thanks.
任何帮助将不胜感激,谢谢。
回答by Eric Mickelsen
You need to bind the name of the property, not its type.
您需要绑定属性的名称,而不是其类型。
C#:
C#:
public class Person
{
...
public List<address> Addresses { get; set; }
...
}
XAML:
XAML:
{Binding Addresses.Count}
Assuming your DataContext
is an object of type Person
.
假设你DataContext
是一个类型的对象Person
。
回答by Robert Rossney
As tehMick says, you can bind using the path Addresses.Count
.
正如 tehMick 所说,您可以使用 path 进行绑定Addresses.Count
。
Note, however, that unless Addresses
is an ObservableCollection<address>
, or some other type that implements INotifyCollectionChanged
, adding and removing addresses won't affect the number that appears in the UI after its initial display. If you need that, you will either need to change the type of the collection in your view model (that's easiest), or implement a property in your view model that exposes the count, and raise the PropertyChanged
event every time you add or remove an address.
但是请注意,除非Addresses
是ObservableCollection<address>
或其他实现 的类型,否则INotifyCollectionChanged
添加和删除地址不会影响初始显示后出现在 UI 中的数字。如果需要,您将需要更改视图模型中集合的类型(这是最简单的),或者在视图模型中实现一个公开计数的属性,并在PropertyChanged
每次添加或删除地址时引发事件.
Edit
编辑
I love reading an answer, thinking, "hey, that's not right," and then realizing I wrote it.
我喜欢阅读答案,想着“嘿,这不对”,然后意识到是我写的。
If you bind to an object that justimplements INotifyCollectionChanged
, the count in the UI won't change if items are added or removed ot the collection. The object alsohas to implement INotifyPropertyChanged
and raise PropertyChanged
when the Count
property changes.
如果绑定到仅实现的对象,INotifyCollectionChanged
则在集合中添加或删除项目时,UI 中的计数不会更改。该对象还必须在属性更改时实现INotifyPropertyChanged
和引发。PropertyChanged
Count
Which, fortunately, ObservableCollection<T>
does. So my answer's not thatwrong.
幸运的是,ObservableCollection<T>
确实如此。所以我的答案并没有那么错误。
回答by Wallstreet Programmer
XAML:
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>
Code behind:
后面的代码:
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
{
}
}
回答by Metro Smurf
To expand on tehMick'sanswer with functional sample code:
要使用功能示例代码扩展tehMick 的答案:
XAML:
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>
Code Behind:
背后的代码:
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;
}
}
}
回答by Mike Guthrie
In my case, Robert's answer got me really close to what I was after. However, I'm adding many items to the list from a service call, and didn't want the event firing for each item. To this end, I took advantage of functionality already built into BindingList
:
就我而言,罗伯特的回答让我非常接近我所追求的。但是,我通过服务调用向列表中添加了许多项目,并且不希望为每个项目触发事件。为此,我利用了已经内置的功能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));
}
Then I simply use it as:
然后我简单地将它用作:
displayItems.RaiseListChangedEvents = false;
serviceItems.ForEach(item => displayItems.Add(item));
displayItems.RaiseListChangedEvents = true;
displayItems.ResetBindings();