繁体   English   中英

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

[英]Accessing a control included in a data template

我有一个ContentControl,用于在CollectionViewSource中显示当前项。

此ContentControl使用DataTemplate来显示RichTextBox。 我想访问RichTextBox,以便将其滚动到预定位置。 但是我似乎无法访问它-如何获得对RichTextBox元素的引用?

非常感谢。

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

使用VisualTreeHelper ,您可以深入查看视觉层次。 假设您有权访问ContentControl本身。 (递归)使用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)...
        }

您可以使用模板的FindName函数,就像您在后面的代码中编写以下代码一样

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

如果将ControlTemplate应用于Control而不是ContentPresenter上的DataTemplate ,则将更加容易

由于模板是按名称分配的,因此在这里可能不是问题。

首先修改模板

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

指定为

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

作为访问控件

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

或(如果已应用模板)

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

但是FindName也适用于DataTemplate ,但是控制模板的条件很少,因此使用此方法可能会遇到异常

例如

此操作仅对应用了此模板的元素有效。

使用ControlTemplate,您可以选择通过调用ApplyTemplate()方法手动应用模板,因此更安全地检索模板对象。

暂无
暂无

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

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