2017-10-12 5 views
1

Im tray_ing pour obtenir un UIElement à partir d'un UserControl au niveau du code Derrière l'utilisation de la méthode FindControl mais en obtenant un objet nul.Impossible d'obtenir une UIElement à partir d'un UserControl à l'aide de FindControl

J'appelle la méthode FindControl de cette façon: Canvas canvas = FindControl (this, typeof (Canvas), "mPDFView"); ScrollViewer touchLayer = FindControl (this, typeof (ScrollViewer), "mtouchLayer");

Où méthode FindControl est:

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

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

+0

@mjwills J'ai traité le message avec le code XAML –

+0

Vous devriez l'obtenir dans [Comment: trouver des éléments générés par ControlTemplate | Microsoft Docs] (https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/how-to-find-controltemplate-generated-elements) – lindexi

Répondre

0

Je suis appelant la méthode FindControl cette façon: toile Canvas = FindControl (ce, typeof (Canvas) , "mPDFView");

Tout d'abord, la façon dont vous invoquez le FindControl est faux, vous devriez l'appeler comme suit:

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

En outre, l'extrait de code est correct. Cela fonctionne bien de mon côté.

Mais attention que dans le code XAML ci-dessus snippet le ContentControl a trois DataTemplates, avec un DataTemplateSelector pour déterminer qui DataTemplate est sélectionné pour l'utilisation. L'élément Canvas n'est situé dans le DataTemplate nommé Pdf, seul le Pdf sélectionné, vous pouvez obtenir l'élément Canvas, sinon avec d'autres DataTemplate sélectionné, l'arbre visuel ne contiendra pas les éléments Canvas.

Afin que la raison la plus probable pour laquelle vous obtenez la valeur null renvoyée est la valeur actuellement sélectionnée DataTemplate n'est pas Pdf.

Puisque vous n'avez pas fourni l'extrait de code relatif DocumentTemplateSelector, j'en crée un simple qui renvoie toujours Pdf DataTemplate qui peut trouver l'élément Canvas bien.

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

Identique au ScrollViewer. Si vous avez encore des problèmes, veuillez fournir un projet reproduit minimal.