简体   繁体   中英

C# - WPF: Get UIElement in nested User Control

I have a xaml file with UserControl inside, there will be another xaml file loaded in.

<UserControl mc:Ignorable="d" d:Title="MainWindow"
         x:Class="TouchControls.Pages.NoticesView.Libov"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:local="clr-namespace:TouchControls.Pages.NoticesView"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008">
<Grid Background="White" Name="LibovLoad" Width="635" Height="400" HorizontalAlignment="Left" VerticalAlignment="Top">

    <!-- here the other xaml file content will dynamically be appended -->
</Grid>

The other xaml file is an UserControl, too:

<UserControl mc:Ignorable="d" d:Title="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008">
        <Grid Margin="20">
            <Slider Height="60" HorizontalAlignment="Right" Margin="20, 0" Maximum="0.3" Minimum="0.2" Orientation="Vertical" Panel.ZIndex="5" Value="0.23" x:Name="ScaleSlider" />
            <Canvas Name="LibovPhoto" Margin="30, 10">
                <Canvas Name="LibovCanvas"></Canvas>
            </Canvas>
        </Grid>
</UserControl>

And that's the method how to load the extern xaml file:

StringReader stringReader = new StringReader(LoadXAMLFile());
XmlReader xmlReader = new XmlTextReader(stringReader);

LibovLoad.Children.Clear();
LibovLoad.Children.Add((UIElement)XamlReader.Load(xmlReader));

Now I would like to access an element in this nested UserControl - the canvas element with the name LibovPhoto . But I don't know, how I could do this. If I try the FindName method, the return value is null (but the xaml file loads correctly!) Up to the UserControl node I come, but not further. I don't know how I get the children of an UserControl element. Can anybody help me? Thanks!

When you load some xaml dynamically the name scopes won't be merged with the user control that will host the xaml. You actually can use FindName() but you should call it on the root xaml element loaded from file.

 FrameworkElement loadedRoot = (FrameworkElement)XamlReader.Load(xmlReader);
 loadedRoot.Loaded += new RoutedEventHandler(loadedRoot_Loaded);
 LibovLoad.Children.Add(loadedRoot);

 void loadedRoot_Loaded(object sender, RoutedEventArgs e)
 {
     Canvas canvas = (sender as FrameworkElement).FindName("LibovPhoto"); // not null
 }

You can use the the VisualTreeHelper to search for the item, as long as you have a control that contains it, you should be able to get the control you're looking for.
Try something like this:

DependencyObject visual = LibovLoad;
DependencyObject parent;

do
{
    if ((childCount = VisualTreeHelper.GetChildrenCount(visual)) > 0)
    {
        parent = visual;
        visual = VisualTreeHelper.GetChild(visual, 0);
    }
    else
    {
        parent = null;
    }
} while (childCount > 0 && !(visual is Canvas));

return parent;

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