如何查找DataTemplate生成的UIElement

时间:2014-01-29 13:57:13

标签: c# wpf visual-tree visualtreehelper

您好我尝试从DataTemplate

中找到生成的UIElement

但是我无法找到我的UserControl,它应该在我的ContentPresenter中 我通过Breakpoint和Snoop查看了控件,但我找不到UserControl

有人可以在我能找到的地方取悦吗?

这是我的测试项目:

App XAML

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

视图

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

代码隐藏

/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        var vm = new VM();
        DataContext =vm;
        CPresenter.Content = vm;
    }
}

3 个答案:

答案 0 :(得分:1)

VisualTreeHelper可以为你提供UserControl,但就像你在另一个答案中提到的那样,你想知道这个属性的确切位置。

您可以使用像这样在私有字段_templateChild上设置的Reflection来获取它。但我仍然建议使用VisualTreeHelper来获得它。

var userControl = typeof(FrameworkElement).GetField("_templateChild", 
           BindingFlags.Instance | BindingFlags.NonPublic).GetValue(CPresenter);

答案 1 :(得分:1)

您不应该直接在ContentPresenter XAML中使用MainWindow ... 它们的用途。取而代之的是,更常见的是使用ContentControl(内部有ContentPresenter):

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

...

此外,您需要命名UserControl

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

使用此设置,您应该能够执行以下操作(改编自MSDN上的How to: Find DataTemplate-Generated Elements页面):

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

答案 2 :(得分:0)

该技术在MSDN上解释How to: Find DataTemplate-Generated Elements 它使用VisualTreeHelper搜索可视树。