【问题标题】:Cannot get a UIElement from a UserControl using FindControl无法使用 FindControl 从 UserControl 获取 UIElement
【发布时间】:2018-03-24 07:35:37
【问题描述】:

我正在使用 FindControl 方法从代码后面的代码中的 UserControl 获取 UIElement,但我得到的是一个空对象。

我这样调用 FindControl 方法: Canvas canvas = FindControl(this, typeof(Canvas), "mPDFView"); ScrollViewer touchLayer = FindControl(this, typeof(ScrollViewer), "mtouchLayer");

FindControl 方法在哪里:

public static T FindControl<T>(UIElement parent, Type targetType, string ControlName) where T : FrameworkElement
    {
        if (parent == null) return null;

        if (parent.GetType() == targetType && ((T)parent).Name == ControlName)
        {
            return (T)parent;
        }
        T result = null;
        int count = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < count; i++)
        {
            UIElement child = (UIElement)VisualTreeHelper.GetChild(parent, i);

            if (FindControl<T>(child, targetType, ControlName) != null)
            {
                result = FindControl<T>(child, targetType, ControlName);
                break;
            }
        }
        return result;
    }

我的 XAML

 <UserControl
x:Class="SalesApp.Views.DocViewer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SalesApp.Views"
xmlns:uc="using:SalesApp.Views.UserControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:SalesApp.ViewModels"
x:Name="root"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ContentControl x:Name="contentControl" Content="{Binding Item}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
        <ContentControl.Resources>
            <DataTemplate x:Key="Media">
                <Grid Background="Black">
                    <MediaElement Source="{Binding MediaSource}" Volume="10" AreTransportControlsEnabled="True" />
                    <StackPanel HorizontalAlignment="Right" VerticalAlignment="Top" Orientation="Horizontal" Visibility="{Binding ShowActionBar, Converter={StaticResource BoolToVisibilityConverter}}" Margin="0,12,12,0">
                        <Button Command="{Binding EmailCommand}" Style="{StaticResource NoBorderButtonStyle}" BorderThickness="0" Visibility="{Binding IsEmailVisible, Converter={StaticResource BoolToVisibilityConverter}}">
                            <BitmapIcon  UriSource="/Assets/icons/icMail.png" Width="50" Height="50" Foreground="{ThemeResource IconsPrimary}"/>
                        </Button>
                        <Button Command="{Binding CloseCommand}" Style="{StaticResource NoBorderButtonStyle}" BorderThickness="0" Margin="0">
                            <BitmapIcon  UriSource="/Assets/icons/icClose(1).png" Width="50" Height="50" Foreground="{ThemeResource IconsPrimary}"/>
                        </Button>
                    </StackPanel>
                </Grid>
            </DataTemplate>
            <DataTemplate x:Key="Image">
                <Grid Background="Black">
                    <Image Source="{Binding MediaSource}" />
                    <StackPanel HorizontalAlignment="Right" VerticalAlignment="Top" Orientation="Horizontal" Visibility="{Binding ShowActionBar, Converter={StaticResource BoolToVisibilityConverter}}" Margin="0,12,12,0">
                        <Button Command="{Binding HDCommand}" Style="{StaticResource NoBorderButtonStyle}" BorderThickness="0" Visibility="{Binding IsLowDefinition, Converter={StaticResource BoolToVisibilityConverter}}">
                            <TextBlock Text="HD" FontSize="35" FontWeight="ExtraBlack" Foreground="White" Margin="0,-4,0,4" />
                        </Button>
                        <Button Command="{Binding EmailCommand}" Style="{StaticResource NoBorderButtonStyle}" BorderThickness="0" Visibility="{Binding IsEmailVisible, Converter={StaticResource BoolToVisibilityConverter}}">
                            <BitmapIcon  UriSource="/Assets/icons/icMail.png" Width="50" Height="50" Foreground="{ThemeResource IconsPrimary}"/>
                        </Button>
                        <Button Command="{Binding CloseCommand}" Style="{StaticResource NoBorderButtonStyle}" BorderThickness="0" Margin="0">
                            <BitmapIcon  UriSource="/Assets/icons/icClose(1).png" Width="50" Height="50" Foreground="{ThemeResource IconsPrimary}"/>
                        </Button>
                    </StackPanel>
                </Grid>
            </DataTemplate>
            <DataTemplate x:Key="Pdf">
                <Grid>
                    <Grid.Resources>
                        <CollectionViewSource x:Name="viewSource" Source="{Binding Pages}" />
                    </Grid.Resources>

                        <Canvas  x:Name="mPDFView"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Tapped="FlipView_Tapped" ScrollViewer.HorizontalScrollMode="Disabled" />
                    <ScrollViewer x:Name="mtouchLayer" Background="Transparent" IsHitTestVisible="True" Tapped="FlipView_Tapped" ScrollViewer.HorizontalScrollMode="Disabled" ScrollViewer.VerticalScrollMode="Disabled"/>
                    <ListView x:Name="pdfThumbnailList" SelectedIndex="{Binding selectedItem}" ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollMode="Enabled" ScrollViewer.VerticalScrollMode="Disabled" ItemsSource="{Binding Source={StaticResource viewSource}}" Height="150" Background="DarkGray" VerticalAlignment="Bottom" Visibility="Collapsed" Tapped="ThumbnailItemTapped" SelectionChanged="ThumbnailList_SelectionChanged">
                        <ListView.ItemContainerStyle>
                            <Style TargetType="ListViewItem">
                                <Setter Property="Margin" Value="0" />
                                <Setter Property="Padding" Value="0" />
                                <Setter Property="VerticalContentAlignment" Value="Stretch" />
                                <Setter Property="VerticalAlignment" Value="Stretch" />
                                <Setter Property="Height" Value="150" />
                            </Style>
                        </ListView.ItemContainerStyle>
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <Image Stretch="Uniform">
                                    <Image.Source>
                                        <BitmapImage UriSource="{Binding ImageSource}" />
                                    </Image.Source>
                                </Image>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                        <ListView.ItemsPanel>
                            <ItemsPanelTemplate>
                                <VirtualizingStackPanel Orientation="Horizontal" VerticalAlignment="Stretch" />
                            </ItemsPanelTemplate>
                        </ListView.ItemsPanel>
                    </ListView>
                    <StackPanel x:Name="pdfActionBar" HorizontalAlignment="Right" VerticalAlignment="Top" Orientation="Horizontal" Visibility="Collapsed" Margin="0,12,12,0">
                        <uc:DocMenuBarUserControl DataContext="{Binding DocMenuVM}" />
                        <Button Command="{Binding CloseCommand}" Style="{StaticResource NoBorderButtonStyle}" BorderThickness="0" Visibility="{Binding ShowCloseAction, ElementName=root, Converter={StaticResource BoolToVisibilityConverter}}">
                            <BitmapIcon  UriSource="/Assets/icons/icClose(1).png" Width="50" Height="50" Foreground="{ThemeResource SalesappsPrimary}"/>
                        </Button>
                        <Button Command="{Binding OpenCommand}" Style="{StaticResource NoBorderButtonStyle}" BorderThickness="0" Visibility="{Binding ShowCloseAction, ElementName=root, Converter={StaticResource InverseBoolToVisibilityConverter}}">
                            <BitmapIcon  UriSource="/Assets/icons/icFullscreen.png" Width="50" Height="50" Foreground="{ThemeResource SalesappsPrimary}"/>
                        </Button>
                    </StackPanel>
                </Grid>

            </DataTemplate>

        </ContentControl.Resources>
        <ContentControl.ContentTemplateSelector>
            <local:DocumentTemplateSelector />
        </ContentControl.ContentTemplateSelector>
    </ContentControl>

    <Border  x:Name="trainingPopup" Background="White" BorderBrush="Gray" BorderThickness="1" Visibility="Collapsed" Height="400" Width="700" CornerRadius="5" >
        <Grid Margin="19">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <TextBlock Text="{Binding DataContext.Translations.training_popup_title, ElementName=contentControl}" FontSize="24" />
            <WebView x:Name="trainingWebContent" Grid.Row="1" ScrollViewer.VerticalScrollMode="Auto" ScrollViewer.HorizontalScrollMode="Disabled">
            </WebView>
            <Button Content="{Binding DataContext.Translations.general_close,ElementName=contentControl}" HorizontalAlignment="Right" Click="closeTrainingClick" Grid.Row="2" RequestedTheme="Light" Margin="0,19,0,0" BorderBrush="Black" BorderThickness="1" />
        </Grid>
    </Border>
</Grid>

【问题讨论】:

标签: c# windows xaml uwp uwp-xaml


【解决方案1】:

我这样调用 FindControl 方法: Canvas canvas = FindControl(this, typeof(Canvas), "mPDFView");

首先,你调用FindControl的方式不对,你应该如下调用:

Canvas canvas = FindControl<Canvas>(this, typeof(Canvas), "mPDFView");

除此之外,代码 sn-p 是正确的。它在我这边运作良好。

但请注意,在上面的 XAML 代码 sn-p 中,ContentControl 有三个DataTemplates,用一个DataTemplateSelector 来确定选择使用哪个DataTemplateCanvas元素只位于名为PdfDataTemplate中,只有Pdf被选中,才能得到Canvas元素,否则与其他DataTemplate被选中,可视化树将不包含@ 987654334@ 元素。

因此,您获得null 值返回的最可能原因是当前选择的DataTemplate 不是Pdf

由于您没有提供 DocumentTemplateSelector 相关代码 sn-p,我创建了一个简单的代码,它始终返回 Pdf DataTemplate,它可以很好地找到 Canvas 元素。

<ContentControl.ContentTemplateSelector>
    <local:DocumentTemplateSelector FirstTemplate="{StaticResource  Pdf}" SecondTemplate="{StaticResource Image}"/>
</ContentControl.ContentTemplateSelector>

public class DocumentTemplateSelector : DataTemplateSelector
{
    public DataTemplate FirstTemplate { get; set; }
    public DataTemplate SecondTemplate { get; set; }   

    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    { 
        return FirstTemplate; 
    }
}

ScrollViewer 相同。如果您仍有问题,请提供一个最小的复制项目。

【讨论】:

    猜你喜欢
    • 2011-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多