简体   繁体   English

访问数据模板中包含的控件

[英]Accessing a control included in a data template

I have a ContentControl which is used to display the current item in a CollectionViewSource. 我有一个ContentControl,用于在CollectionViewSource中显示当前项。

This ContentControl used a DataTemplate to display a RichTextBox. 此ContentControl使用DataTemplate来显示RichTextBox。 I want to have access to the RichTextBox so I can scroll it to a predetermined location. 我想访问RichTextBox,以便将其滚动到预定位置。 However I can't seem to access it - how would I obtain a reference to the RichTextBox element? 但是我似乎无法访问它-如何获得对RichTextBox元素的引用?

Many thanks. 非常感谢。

<CollectionViewSource x:Key="Results"
                      Source="{Binding Results}">
</CollectionViewSource>


<Grid.Resources>
    <!--Data Templates-->
    <DataTemplate DataType="{x:Type VFClass:Script}"
                  x:Key="scriptTemplate">
        <RichTextBox x:Name="ScriptViewRichTextBox"
                     local:RichTextBoxHelper.DocumentXaml="{Binding HighlightedRTF, IsAsync=False}"
                     BorderThickness="0"
                     ScrollViewer.CanContentScroll="True"
                     ScrollViewer.VerticalScrollBarVisibility="Auto"
                     IsReadOnly="{Binding ReadOnly}"
                     Margin="0"
                     ContextMenuOpening="RichTextBox_ContextMenuOpening"
                     Padding="5">
        </RichTextBox>
    </DataTemplate>
</Grid.Resources>



<ContentControl x:Name="ScriptText"
                Grid.Row="1"
                Margin="0"
                Content="{Binding IsAsync=False, Source={StaticResource Results}}"
                ContentTemplate="{StaticResource scriptTemplate}" />

Using VisualTreeHelper , you can drill down in the visual hierarchy. 使用VisualTreeHelper ,您可以深入查看视觉层次。 Assuming you have access to the ContentControl itself. 假设您有权访问ContentControl本身。 (Recursively) use VisualTreeHelper.GetChildrenCount and VisualTreeHelper.GetChild to access the actual visual tree of the ContentControl , until you reach the RichTextBox you're interested in: (递归)使用VisualTreeHelper.GetChildrenCountVisualTreeHelper.GetChild访问ContentControl的实际可视树,直到到达您感兴趣的RichTextBox为止:

        int count = VisualTreeHelper.GetChildrenCount(contentControl);
        for (int i = 0; i < count; ++i)
        {
            DependencyObject d = VisualTreeHelper.GetChild(contentControl, i);
            if (d is RichTextBox)
            {
                //...do your thing
            }

            //  recurse (if necessary)...
        }

You can use FindName function of template like you have write in following code in you code behind 您可以使用模板的FindName函数,就像您在后面的代码中编写以下代码一样

var template = ControlWhereTemplateAssign.Template;
var myControl = (RichTextBox)template.FindName("ScriptViewRichTextBox", ControlWhereTemplateAssign);

this would be much easier if a ControlTemplate is applied on the Control instead of a DataTemplate on the ContentPresenter 如果将ControlTemplate应用于Control而不是ContentPresenter上的DataTemplate ,则将更加容易

since the template is being assigned by name so it may not be an issue here. 由于模板是按名称分配的,因此在这里可能不是问题。

start by modifying the template 首先修改模板

<ControlTemplate x:Key="scriptTemplate">
    <RichTextBox x:Name="ScriptViewRichTextBox"
                 ... >
    </RichTextBox>
</ControlTemplate>

specify as 指定为

<ContentControl x:Name="ScriptText"
                ...
                Template="{StaticResource scriptTemplate}">

access the control as 作为访问控件

    if (ScriptText.ApplyTemplate())
    {
        RichTextBox rtb = (RichTextBox)ScriptText.Template.FindName("ScriptViewRichTextBox", ScriptText);
    }

or (if template already applied) 或(如果已应用模板)

    RichTextBox rtb = (RichTextBox)ScriptText.Template.FindName("ScriptViewRichTextBox", ScriptText);

however FindName applies to DataTemplate as well but there are few conditions which govern the template so you may encounter exceptions using this method 但是FindName也适用于DataTemplate ,但是控制模板的条件很少,因此使用此方法可能会遇到异常

eg 例如

This operation is valid only on elements that have this template applied. 此操作仅对应用了此模板的元素有效。

using ControlTemplate you have option to apply template manually by calling ApplyTemplate() method, hence more safe to retrieve the template objects. 使用ControlTemplate,您可以选择通过调用ApplyTemplate()方法手动应用模板,因此更安全地检索模板对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM