如何从WPF中的子控件访问包含的Canvas控件

本文关键字:控件 访问 包含 Canvas WPF | 更新日期: 2023-09-27 18:10:20

我有一个具有以下XAML定义的Canvas:

<Canvas Height="201" VerticalAlignment="Top"
        Name="myCanvas"
        KeyDown="KeyEvent" >
    <local:MyGlyphsElement x:Name="mge" />
    <Line Name="myLine" Stroke="Blue" StrokeThickness="2"></Line>
</Canvas>

MyGlyphsElement控件的后置代码文件中,如何访问myLinemyCanvas ?(MyGlyphsElementFrameworkElement衍生而来)

我的目的是能够在运行时为myCanvas子控件添加控件以及操纵myLine属性,如笔画宽度等。

编辑:

public partial class MyGlyphsElement: FrameworkElement
    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);  // Good practice.
        ...
        Canvas cp = (Canvas)this.Parent;
        // Now what? How do I access myLine?

如何从WPF中的子控件访问包含的Canvas控件

为解析Visual Tree做一些漂亮的扩展,如下所示(这将允许您通过指定的名称获得元素):

public static class DependentObjectExtensions
{
    public static IEnumerable<DependencyObject> GetChildren(this DependencyObject parent)
    {
        for (int i = 0, length = VisualTreeHelper.GetChildrenCount(parent); i < length; i++)
        {
            yield return VisualTreeHelper.GetChild(parent, i);
        }
    }
    public static T FindChild<T>(this DependencyObject parent, string name, bool drillDown = false)
        where T : FrameworkElement
    {
        if(parent != null)
        {
            var elements = parent.GetChildren().OfType<T>();
            return drillDown
                ? elements.Select(x => FindChild<T>(x, name, true)).FirstOrDefault(x => x != null)
                : elements.FirstOrDefault(x => x.Name == name);
        }
        return null;
    }
}

然后,将MyGlyphsElement.OnRender更改为如下所示:

    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);
        var myLine = Parent.FindChild<Line>("myLine");
        //TODO: Do stuff with your line.
    } 

如果您需要进一步的说明,请告诉我,我会根据您的反馈修改我的回复。