绑定到Children.Count [英] Binding to Children.Count
问题描述
我使用的形式结合
{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=Rows}
尽管在XAML中添加的孩子,当我在转炉突破,该值始终为0。
Despite adding the children in xaml, when I break in the converter, the value is always 0.
我认为正在发生的是,孩子们不会添加后才这种结合被调用。
What I assume is going on is that the children are not added until after this binding is called.
我也假设结合被打破后,它被称为曾经因为.Count之间是一个只读属性(我有,我必须在属性添加一个空二传手维持约束力和愚弄WPF之前类似的问题)因此绑定儿童一旦被添加不更新。
I also assume that the binding is broken after it's been called once because .Count is a readonly property (I've had a similar problem before where I had to add an empty setter in the property to maintain the binding and fool WPF) hence the binding not updating once children are added.
不过,我卡在那里你拿出解决问题的办法,并使其发挥作用... = /
However, I'm stuck on the bit where you come up with a solution for the problem and make it work... =/
<UniformGrid x:Name="MyUniformGrid"
Rows="{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=R}"
Columns="{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=C}">
<Button Content="Hello, World!" />
<Button Content="Hello, World!" />
<Button Content="Hello, World!" />
<Button Content="Hello, World!" />
<Button Content="Hello, World!" />
<Button Content="Hello, World!" />
</UniformGrid>
谢谢,
RABIT
Thanks, Rabit
推荐答案
这是因为 UIElementCollection
(即儿童的类型
属性)不会引发通知时一个新的项目添加或删除,因此不会刷新的结合
That's because UIElementCollection
(the type of the Children
property) doesn't raise notifications when a new item is added or removed, so the binding isn't refreshed
您可以,但是,创建自己的定制 UniformGrid
,并覆盖 CreateUIElementCollection
属性创建的实例自定义集合继承 UIElementCollection
和农具 INotifyCollectionChanged
。
You could, however, create your own custom UniformGrid
, and override the CreateUIElementCollection
property to create an instance of a custom collection that inherits UIElementCollection
and implements INotifyCollectionChanged
.
下面是一个基本的实现:
Here's a basic implementation :
ObservableUIElementCollection
public class ObservableUIElementCollection : UIElementCollection, INotifyCollectionChanged, INotifyPropertyChanged
{
public ObservableUIElementCollection(UIElement visualParent, FrameworkElement logicalParent)
: base(visualParent, logicalParent)
{
}
public override int Add(UIElement element)
{
int index = base.Add(element);
var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, element, index);
OnCollectionChanged(args);
OnPropertyChanged("Count");
OnPropertyChanged("Item[]");
return index;
}
public override void Clear()
{
base.Clear();
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
OnPropertyChanged("Count");
OnPropertyChanged("Item[]");
}
public override void Insert(int index, UIElement element)
{
base.Insert(index, element);
var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, element, index);
OnCollectionChanged(args);
OnPropertyChanged("Count");
OnPropertyChanged("Item[]");
}
public override void Remove(UIElement element)
{
int index = IndexOf(element);
if (index >= 0)
{
RemoveAt(index);
var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, element, index);
OnCollectionChanged(args);
OnPropertyChanged("Count");
OnPropertyChanged("Item[]");
}
}
public override UIElement this[int index]
{
get
{
return base[index];
}
set
{
base[index] = value;
var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, index);
OnCollectionChanged(args);
OnPropertyChanged("Item[]");
}
}
public event NotifyCollectionChangedEventHandler CollectionChanged;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
var handler = CollectionChanged;
if (handler != null)
handler(this, e);
}
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
MyUniformGrid
public class MyUniformGrid : UniformGrid
{
protected override UIElementCollection CreateUIElementCollection(FrameworkElement logicalParent)
{
return new ObservableUIElementCollection(this, logicalParent);
}
}
XAML
<local:MyUniformGrid x:Name="MyUniformGrid"
Rows="{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=R}"
Columns="{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=C}">
<Button Content="Hello, World!" />
<Button Content="Hello, World!" />
<Button Content="Hello, World!" />
<Button Content="Hello, World!" />
<Button Content="Hello, World!" />
<Button Content="Hello, World!" />
</local:MyUniformGrid>
这篇关于绑定到Children.Count的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!