简体   繁体   中英

WPF: Select child control within a Canvas

A quick question regarding WPF: How can I select child elements within a Canvas/Grid?

For example, in the following XAML snippet:

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

...how can I access border1 within parentCanvas_MouseMove and parentCanvas_MouseLeave methods?

Also, the way I access the canvas itself within the event handlers looks a bit hacky, I do something along the lines of:

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

Is that the right way of accessing it or is there a more elegant way of doing this?

Many thanks,
Hamza.

When you name a control with a Name attribute, it will generate a member in the class, so you should be able to access them by name:

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

If the controls are part of a ControlTemplate or DataTemplate, then you would need to get a reference to the parent and look it up in the template. For example, if your XAML is part of a DataTemplate, you would have to do something like this:

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

In any case, casting the sender parameter to the appropriate type is perfectly reasonable, and it lets you make your event handlers more reusable.


If you don't have a name for your canvas, you can also use the Children property of the Canvas to iterate through its visual 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();
}

Finally, if you have a visual that isn't a Panel, you can use VisualTreeHelper.GetChildrenCount and VisualTreeHelper.GetChild :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM