如何设置已强制转换为 Framework 元素的 UIControl 的依赖项 poperty 的值?

How do I set the value of a dependency poperty of a UIControl that has been cast to a Framework Element?

提问人:Joe Osborne 提问时间:9/17/2023 最后编辑:marc_sJoe Osborne 更新时间:9/18/2023 访问量:43

问:

我想为二叉树构建一个 UI 控件 - 就像 Stochastic Calculus for Finance I: The Binomial Asset Pricing Model 中使用的控件一样

我当前的实现有我想要的节点绘制。这是使用传递到 ItemsControl 的自定义 UI 元素(当前只是一个椭圆 [node] 和一条线 [edge])。我已经在包含此布局的控件中实现了 and 方法以实现此布局。我的计划是行的,这是行的,一旦节点全部就位,就将行的目标设置为方法末尾节点的父元素。我无法将 的子元素向下转换为自定义 UI 元素,因此我无法直接修改成员。MeasureOverride()ArrangeOverride()ItemsControlArrangeOverride()ItemsControlParentCoordinate

所以我正在尝试使用该函数访问此属性,这似乎有效。甚至该功能似乎也有效。但是,这似乎对 UI 没有影响。我不确定设置值后(或两者兼而有之)是否是我设置值或适当更新 UI 的问题!GetValue()SetValue()

任何帮助将不胜感激 - 此外,欢迎对我的项目的实施提出任何其他建议。

我所拥有的与我想要的

用于 ref 的 Github 存储库

下面详细介绍了我如何尝试设置线路的目的地。

    protected virtual Size ArrangeOverride(Size finalSize)
    {
        foreach (ContentPresenter child in Children)
        {
           // Arrange UI Elements
        }

        foreach (ContentPresenter child in Children)
        {
            var parentNode = child.Content as INode<State>;
            var UIParent = child as FrameworkElement;

            foreach (ContentPresenter otherChild in Children)
            {
                var otherNodeChild = otherChild.Content as INode<State>;
                if (otherNodeChild.Previous != parentNode)
                    continue;

                var uiOtherChild = otherChild as FrameworkElement;
                var originalPos = uiOtherChild.GetValue(UINode.ParentCoordinateProperty); // Check current value for debugging
                var parentCoords =  UIParent.PointToScreen(new Point(0, 0)); // Get correct value for the line to be drawn to
                otherChild.SetCurrentValue( UINode.ParentCoordinateProperty , parentCoords); // set the value
                var changedPos = uiOtherChild.GetValue(UINode.ParentCoordinateProperty); // verify in debug that the value has been updated
            }
        }

        return finalSize;
    }

下一个代码片段演示了我如何尝试在 XAML 中设置行的目标。

<Line Stroke='Black'
          StrokeThickness='3'
          X1='{Binding centre}'
          Y1='{Binding centre}'
          X2='{Binding Path=DataContext.ParentCoordinate.X ,Mode=TwoWay}'
          Y2='{Binding Path=DataContext.ParentCoordinate.Y ,Mode=TwoWay}' />

最后,我在元素中设置依赖项属性的方式

    public event PropertyChangedEventHandler? PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

    // Where the Child-To-Parent line connects to 
    public static readonly DependencyProperty ParentCoordinateProperty =
        DependencyProperty.Register("ParentCoordinate",  
                                    typeof(System.Windows.Point), 
                                    typeof(UINode), 
                                    new PropertyMetadata(new PropertyChangedCallback(OnParentCoordinatePropertyChangedCallBack))); 

    public System.Windows.Point ParentCoordinate
    {
        get { return (System.Windows.Point)GetValue(ParentCoordinateProperty); }
        set 
        { 
            SetValue(ParentCoordinateProperty, value);
            OnPropertyChanged("Text");
        }
    }

    private static void OnParentCoordinatePropertyChangedCallBack(DependencyObject d,
                              DependencyPropertyChangedEventArgs e)
    {
        UINode UserControl1Control = d as UINode;

        if (UserControl1Control != null)
            UserControl1Control.OnParentCoordinateChanged(e);   
    }

    protected virtual void OnParentCoordinateChanged(DependencyPropertyChangedEventArgs e)
    {
        OnPropertyChanged("ParentCoordinate");
    }
C# WPF 二进制树 定量金融

评论

0赞 Clemens 9/18/2023
从你的描述来看,你在做什么似乎是错误的。ItemsControl 的项布局由其 ItemsPanel 完成,默认情况下,ItemsPanel 是 StackPanel,但可以是任何其他 Panel,例如 Canvas 或自定义 Panel。作为 ItemsControl 的默认项容器的 ContentPresenters 将成为 ItemsPanel 的直接子元素。
0赞 Clemens 9/18/2023
还可以创建一个自定义 ItemsControl,该控件通过重写 GetContainerForItemOverride 方法创建自定义项容器元素。
0赞 Joe Osborne 9/18/2023
@Clemens,看起来这可能只是工作。我会在本周下班后尽量抽出时间来实施这一点,并在这里发布我的结果。感谢您的帮助!

答: 暂无答案