Snap to children.

I use form binding

{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=Rows}

Despite adding children to xaml, when I break the converter, the value is always 0.

I believe that it happens that children are not added until this binding is triggered.

I also assume that the binding was broken after it was called once because .Count is a readonly property (I had a similar problem before I had to add an empty setter to the property to support binding and fool WPF), therefore the binding does not update after adding child elements.

However, I was stuck on a bit where you came up with a solution to the problem and made 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>

Thanks Rabit

+3
source share
1

, 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));
    }
}

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>
+8

Source: https://habr.com/ru/post/1760484/


All Articles