绑定未更新 - 添加检测面板儿童

发布于 2024-11-08 14:43:09 字数 2225 浏览 0 评论 0原文

我目前正在实现一个继承自 Panel 的布局容器,并且能够检测 Panel.Children 中的更改,并检测新元素/删除的元素。

目前,我有一个绑定到Panel.Children.Count 值的依赖属性,这非常笨重,但我不知道创建此类侦听器的更好方法。

public abstract class MyLayoutContainer : Panel
{
    private Binding countBinding;

    // ctor...

    private void InitializeBinding()
    {
        countBinding = new Binding("Count");
        countBinding.Source = this.Children;
        // Using the comment below instead of "Count"
        // in the Binding constructor throws an error
        //countBinding.Path = new PropertyPath(UIElementCollection.CountProperty);
        countBinding.Mode = BindingMode.OneWay;
        BindingOperations.SetBinding(this, MyLayoutContainer.BoundChildCountProperty, countBinding);
    }

    // ...

    private static readonly DependencyProperty BoundChildCountProperty
        = DependencyProperty.Register
        (
            "BoundChildCount",
            typeof(int),
            typeof(MyLayoutContainer),
            new PropertyMetadata(0, ChildCountChange)
        );

    private static int GetBoundChildCount(MyLayoutContainer depObj)
    {
        return (int)depObj.GetValue(BoundChildCountProperty);
    }
    private static void SetBoundVisibility(MyLayoutContainer depObj, int value)
    {
        depObj.SetValue(BoundChildCountProperty, value);
    }


    private static void ChildCountChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        MyLayoutContainer mlc = d as MyLayoutContainer;

        // For testing, this function is currently empty
        // however normally it checks children against a
        // shadow list, or will remove them as they're
        // added.
        mlc.ChildrenChanged(e.OldValue, e.NewValue);
    }
}

问题是它只更新一次。几乎就像我设置了 BindingMode.OneTime 一样,但事实并非如此。当我检查 BoundChildCountPropertythis.Children.Count 时,我得到 1 和 4。我不知道发生了什么,因为我使用了完全相同的绑定方法到另一个对象的可见性来创建“侦听器”。

此外,当它加载所有对象时,我在 XAML 设计器中获得了更好的功能(当我将它们放入其中时,有很多烦人的 MessageBox...)。

请,如果有人知道更好的方法,或者可以看到我做错了什么,我将非常非常感激!

编辑 - 更多信息: 我的最终目标是创建一个灵活的类,可以扩展任何当前的面板类(例如 Grids 和 StackPanels),并且因为它们密封了覆盖函数,所以我希望找到一种解决方法来检测添加的子项等。

I am currently implementing a Layout Conainer that inherits from Panel and is able to detect a change in Panel.Children, and detect the new element/deleted element.

At the moment, I've got a Dependency Property that is bound to the Panel.Children.Count value, which is terribly clunky, but I don't know a better way of creating such listeners.

public abstract class MyLayoutContainer : Panel
{
    private Binding countBinding;

    // ctor...

    private void InitializeBinding()
    {
        countBinding = new Binding("Count");
        countBinding.Source = this.Children;
        // Using the comment below instead of "Count"
        // in the Binding constructor throws an error
        //countBinding.Path = new PropertyPath(UIElementCollection.CountProperty);
        countBinding.Mode = BindingMode.OneWay;
        BindingOperations.SetBinding(this, MyLayoutContainer.BoundChildCountProperty, countBinding);
    }

    // ...

    private static readonly DependencyProperty BoundChildCountProperty
        = DependencyProperty.Register
        (
            "BoundChildCount",
            typeof(int),
            typeof(MyLayoutContainer),
            new PropertyMetadata(0, ChildCountChange)
        );

    private static int GetBoundChildCount(MyLayoutContainer depObj)
    {
        return (int)depObj.GetValue(BoundChildCountProperty);
    }
    private static void SetBoundVisibility(MyLayoutContainer depObj, int value)
    {
        depObj.SetValue(BoundChildCountProperty, value);
    }


    private static void ChildCountChange(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        MyLayoutContainer mlc = d as MyLayoutContainer;

        // For testing, this function is currently empty
        // however normally it checks children against a
        // shadow list, or will remove them as they're
        // added.
        mlc.ChildrenChanged(e.OldValue, e.NewValue);
    }
}

The problem is that it is only updating once. It's almost as though I've set BindingMode.OneTime which is not the case. When I check the BoundChildCountProperty against this.Children.Count I get 1 and 4. I have no idea what's going on, because I've used this exact same method for binding to the visibility of another object to create a 'listener'.

Furthermore, I get much better functionality out of it in the XAML Designer (so many annoying MessageBoxes when I've got them in there...) when it's loading all the objects.

Please, if anyone knows a better way of doing this, or can see what I've done wrong, I will be very, very grateful!

EDIT - Further Information:
My end goal is to create a flexible class that can extended any of the current Panel classes (such as Grids and StackPanels) and because they seal the override functions I was hoping to find a workaround for detecting the children added, etc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谎言 2024-11-15 14:43:09

您应该重写方法 ArrangeOverrideMeasureOverride,这些是您进行自定义布局的地方。他们会因各种原因被调用,其中之一是每当Children成员资格发生变化时。

You should be overriding the methods ArrangeOverride and MeasureOverride, these are where you do your custom layout. They will be called for various reasons one being whenever the Children membership changes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文