C# - WPF:在嵌套用户控件中获取UIElement

时间:2014-05-01 02:01:38

标签: c# wpf xaml user-controls nested

我有一个带有UserControl的xaml文件,会加载另一个xaml文件。

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

另一个xaml文件也是UserControl:

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

这就是如何加载extern xaml文件的方法:

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

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

现在我想访问这个嵌套的UserControl中的一个元素 - 名为 LibovPhoto 的canvas元素。但我不知道,我怎么能做到这一点。如果我尝试FindName方法,返回值为null(但正确加载xaml文件!)直到我来的UserControl节点,但不是更远。我不知道如何获得UserControl元素的子元素。 有谁能够帮我?谢谢!

2 个答案:

答案 0 :(得分:2)

当您动态加载某个xaml时,名称范围不会与将托管xaml的用户控件合并。您实际上可以使用FindName(),但您应该在从文件加载的根xaml元素上调用它。

 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
 }

答案 1 :(得分:0)

您可以使用VisualTreeHelper搜索该项目,只要您拥有包含它的控件,您就可以获得您正在寻找的控件。
尝试这样的事情:

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;