1

Hi i try to find the generated UIElement from a DataTemplate

but i'm not able to find my UserControl which should be somewhere in my ContentPresenter i looked in to the control via a Breakpoint and Snoop but i cant find the UserControl

can someone please enlight where i can find it?

Here my Test Project:

App XAML

<Application.Resources>
    <DataTemplate x:Name="TESTTemplate" DataType="{x:Type vmv:VM}">
        <vmv:MyView/>
    </DataTemplate>
</Application.Resources>

View

<UserControl ...>
    <DataGrid ItemsSource="{Binding MyItems}"/>
</UserControl>

VM

public class VM
{
    private ObservableCollection<MyRow> myItems;

    public ObservableCollection<MyRow> MyItems
    {
        get { return myItems; }
        set { myItems = value; }
    }

    public VM()
    {
        myItems = new ObservableCollection<MyRow>();
        myItems.Add(new MyRow { Text = "a", Number = 1 });
        myItems.Add(new MyRow { Text = "s", Number = 2 });
        myItems.Add(new MyRow { Text = "d", Number = 3 });
        myItems.Add(new MyRow { Text = "f", Number = 4 });
    }
}

public class MyRow
{
    public string Text { get; set; }

    public int Number { get; set; }
}

MainWindow XAML

<Window x:Class="MyPrinterAPI.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
    <ContentPresenter Name="CPresenter">

    </ContentPresenter>
    </StackPanel>
</Window>

CodeBehind

/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        var vm = new VM();
        DataContext =vm;
        CPresenter.Content = vm;
    }
}
WiiMaxx
  • 5,322
  • 8
  • 51
  • 89

3 Answers3

1

VisualTreeHelper can get you UserControl but like you mentioned in another answer, you want to know where exactly this property is set.

You can get that using Reflection which is set on private field _templateChild like this. But still i would suggest use VisualTreeHelper to get that.

var userControl = typeof(FrameworkElement).GetField("_templateChild", 
           BindingFlags.Instance | BindingFlags.NonPublic).GetValue(CPresenter);
Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
1

You shouldn't be using a ContentPresenter directly in your MainWindow XAML... that is not what they are for. Instead of that, it is more common to use a ContentControl (which has its own ContentPresenter inside):

<Window x:Class="MyPrinterAPI.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <ContentControl Name="ViewControl" Content="{Binding ViewModel}" 
            ContentTemplate="{StaticResource TESTTemplate}" />
    </StackPanel>
</Window>

...

Also, you'd need to name your UserControl:

<DataTemplate x:Name="TESTTemplate" DataType="{x:Type vmv:VM}">
    <vmv:MyView name="View" />
</DataTemplate>

Using this setup, you should be able to do the following (adapted from the How to: Find DataTemplate-Generated Elements page on MSDN):

// Getting the ContentPresenter from the ViewControl
ContentPresenter myContentPresenter = 
    VisualTreeHelper.GetChild(ViewControl, 0) as ContentPresenter;    
if (myContentPresenter != null)
{
    // Finding View from the DataTemplate that is set on that ContentPresenter
    DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
    MyView myView = (MyView)myDataTemplate.FindName("View", myContentPresenter);

    // Do something to the myView control here
}
Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • thanks for your effort. My Question wasn't clear enough i was just wonder where i can see the value in the debugger – WiiMaxx Jan 29 '14 at 15:42
  • If you put a breakpoint where it says `// Do something to the myView control here`, then you could just use the `myView` variable to see the value in the debugger. – Sheridan Jan 29 '14 at 15:56
  • Rohit Vats answer wars was i was looking for because i was surprise where the ContentPresenter stores the UserControl – WiiMaxx Jan 29 '14 at 16:09
  • Thanks for your suggestion but the problem is when should I write this code to find the `View`? I've tried `OnVisualChildrenChanged` `OnContentTemplateChanged` `OnApplyTemplate` but none of them works. If I find it after `Loaded`, the user will see a layout refreshing which is unexpected. – walterlv Aug 12 '19 at 08:38
0

The technique is explained on MSDN How to: Find DataTemplate-Generated Elements It uses VisualTreeHelper to search through the visual tree.

bouvierr
  • 3,563
  • 3
  • 27
  • 32
  • i know that but why can't i find it in the control it self? there should be some property where can see my Usercontrol – WiiMaxx Jan 29 '14 at 14:14