绑定到Children.Count [英] Binding to Children.Count

查看:142
本文介绍了绑定到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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆