1

嗨,我尝试从 DataTemplate 中找到生成的 UIElement

但我无法找到应该在我的 ContentPresenter 中某处的 UserControl 我通过断点和 Snoop 查看了控件,但我找不到 UserControl

有人可以启发我在哪里可以找到它吗?

这是我的测试项目:

应用 XAML

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

看法

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

虚拟机

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

主窗口 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;
    }
}
4

3 回答 3

1

VisualTreeHelper可以让您获得 UserControl 但就像您在另一个答案中提到的那样,您想知道该属性的确切设置位置。

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

var userControl = typeof(FrameworkElement).GetField("_templateChild", 
           BindingFlags.Instance | BindingFlags.NonPublic).GetValue(CPresenter);
于 2014-01-29T14:35:31.400 回答
1

您不应该ContentPresenter直接在您的MainWindowXAML 中使用 a ...这不是它们的用途。取而代之的是,更常见的是使用 a 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
}
于 2014-01-29T14:55:45.670 回答
0

该技术在 MSDN How to: Find DataTemplate-Generated Elements上 进行了说明。它使用 VisualTreeHelper 搜索可视化树。

于 2014-01-29T14:07:14.913 回答