WPF:在画布中选择子控件

Ham*_*mza 2 c# wpf visual-studio-2010 wpf-controls

关于 WPF 的一个快速问题:如何在画布/网格中选择子元素?

例如,在以下 XAML 代码段中:

    <Canvas Name="parentCanvas" Width="200" Height="200" Background="AliceBlue" MouseMove="parentCanvas_MouseMove" MouseLeave="parentCanvas_MouseLeave">
        <Border Name="border1" Margin="10" Height="100" Width="180" Background="Maroon" Canvas.Top="47" />
    </Canvas>
Run Code Online (Sandbox Code Playgroud)

...如何访问border1内部parentCanvas_MouseMoveparentCanvas_MouseLeave方法?

此外,我在事件处理程序中访问画布本身的方式看起来有点古怪,我做了一些事情:

    private void parentCanvas_MouseLeave(object sender, MouseEventArgs e)
    {
        Canvas c = (Canvas)sender;
        c.Background = Brushes.Blue;
    }
Run Code Online (Sandbox Code Playgroud)

这是访问它的正确方式还是有更优雅的方式来做到这一点?

非常感谢,
哈姆扎。

Qua*_*ter 5

当您使用Name属性命名控件时,它将在类中生成一个成员,因此您应该能够通过名称访问它们:

private void parentCanvas_MouseLeave(object sender, MouseEventArgs e)
{
    Canvas c = parentCanvas;
    c.Background = Brushes.Blue;
    Border b = border1;
}
Run Code Online (Sandbox Code Playgroud)

如果控件是 ControlTemplate 或 DataTemplate 的一部分,则您需要获取对父项的引用并在模板中查找它。例如,如果您的 XAML 是 DataTemplate 的一部分,则必须执行以下操作:

private void parentCanvas_MouseLeave(object sender, MouseEventArgs e)
{
    Canvas c = (Canvas)sender;
    var contentPresenter = (ContentPresenter)c.TemplatedParent;
    var b = contentPresenter.ContentTemplate.FindName(
        "border1", contentPresenter);
}
Run Code Online (Sandbox Code Playgroud)

在任何情况下,将sender参数转换为适当的类型是完全合理的,它可以让您的事件处理程序更可重用。


如果您的画布没有名称,您还可以使用画布的Children属性来遍历其视觉子级:

private void parentCanvas_MouseLeave(object sender, MouseEventArgs e)
{
    Canvas c = (Canvas)sender;
    var firstChild = c.Children[0];
    var firstBorderChild = c.Children.OfType<Border>().FirstOrDefault();
}
Run Code Online (Sandbox Code Playgroud)

最后,如果您的视觉对象不是面板,则可以使用VisualTreeHelper.GetChildrenCountVisualTreeHelper.GetChild

for (int childIndex = 0; 
     childIndex < VisualTreeHelper.GetChildrenCount(c); 
     childIndex++)
{
    var child = VisualTreeHelper.GetChild(c, childIndex);
}
Run Code Online (Sandbox Code Playgroud)