绑定到Children.Count

Dea*_*bit 4 c# wpf xaml binding

我正在使用表单的绑定

{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=Rows}
Run Code Online (Sandbox Code Playgroud)

尽管在xaml中添加了子节点,但当我在转换器中中断时,值始终为0.

我假设正在进行的是在调用此绑定之后才会添加子项.

我也假设绑定在被调用一次后被破坏,因为.Count是一个只读属性(我之前有一个类似的问题,我必须在属性中添加一个空的setter来维护绑定并愚弄WPF)因此添加子项后绑定不更新.

但是,我坚持认为你想出一个问题的解决方案,让它工作...... = /

<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>
Run Code Online (Sandbox Code Playgroud)

谢谢,拉比特

Tho*_*que 9

这是因为UIElementCollection(Children属性的类型)在添加或删除新项目时不会引发通知,因此绑定不会刷新

但是,您可以创建自己的自定义UniformGrid,并覆盖该CreateUIElementCollection属性以创建继承UIElementCollection和实现的自定义集合的实例INotifyCollectionChanged.

这是一个基本的实现:

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));
    }
}
Run Code Online (Sandbox Code Playgroud)

MyUniformGrid

public class MyUniformGrid : UniformGrid
{
    protected override UIElementCollection CreateUIElementCollection(FrameworkElement logicalParent)
    {
        return new ObservableUIElementCollection(this, logicalParent);
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)