C# 如何在应用于ContentPresenter的DataTemplate中找到元素?

C# 如何在应用于ContentPresenter的DataTemplate中找到元素?,c#,wpf,C#,Wpf,我已经创建了一个AddressInput控件,供用户输入地址。控件的外观将因使用位置而异,因此我提供了一个名为AddressTemplate的DataTemplate属性 默认样式如下所示: <Style TargetType="{x:Type addressUI:AddressInput}"> <Setter Property="AddressTemplate" Value="{StaticResource DefaultAddressTemp

我已经创建了一个AddressInput控件,供用户输入地址。控件的外观将因使用位置而异,因此我提供了一个名为AddressTemplate的DataTemplate属性

默认样式如下所示:

<Style TargetType="{x:Type addressUI:AddressInput}">
    <Setter Property="AddressTemplate"
            Value="{StaticResource DefaultAddressTemplate}" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type addressUI:AddressInput}">
                <GroupBox Header="Address">
                    <ContentPresenter ContentTemplate="{Binding Path=AddressTemplate, RelativeSource={RelativeSource TemplatedParent}}"
                                      Content="{Binding Path=Address, RelativeSource={RelativeSource TemplatedParent}}"
                                      x:Name="PART_AddressPresenter" />
                </GroupBox>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
public override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    var addressPresenter = Template.FindName("PART_AddressPresenter", this) as ContentPresenter;
}
Dispatcher.BeginInvoke( new Action(() =>
{
    // Call FindName here
}), System.Windows.Threading.DispatcherPriority.Render );
现在如何获取AddressTemplate中包含的“PART\u CountriesList”

我试过这个:

var countriesList=AddressTemplate.FindName(“PART\u countriesList”,addressPresenter)

引发异常,因为addressPresenter尚未应用其模板。我知道ContentPresenter具有OnApplyTemplate覆盖,但是为了这种用途而扩展它似乎很愚蠢


我想如果我要扩展ContentPresenter,我会创建一个新的可重用版本,在OnApplyTemplate方法执行时触发事件。这可能会解决我的问题,但似乎很疯狂。有更好的方法吗?

我很好奇是否有人有“正确”的方法来做这件事,但有了FindName,我总是求助于这样的方法:

<Style TargetType="{x:Type addressUI:AddressInput}">
    <Setter Property="AddressTemplate"
            Value="{StaticResource DefaultAddressTemplate}" />

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type addressUI:AddressInput}">
                <GroupBox Header="Address">
                    <ContentPresenter ContentTemplate="{Binding Path=AddressTemplate, RelativeSource={RelativeSource TemplatedParent}}"
                                      Content="{Binding Path=Address, RelativeSource={RelativeSource TemplatedParent}}"
                                      x:Name="PART_AddressPresenter" />
                </GroupBox>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
public override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    var addressPresenter = Template.FindName("PART_AddressPresenter", this) as ContentPresenter;
}
Dispatcher.BeginInvoke( new Action(() =>
{
    // Call FindName here
}), System.Windows.Threading.DispatcherPriority.Render );
但是,这可能会导致闪烁,因为您要等到数据模板完成并呈现之后才能开始练习代码,因此如果您尝试执行的操作会影响控件的外观,那么这并不总是一个很好的选择