Question

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;
    }
}
Was it helpful?

Solution

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

OTHER TIPS

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
}

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top