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

本文关键字:ContentPresenter 应用于 元素 DataTemplate | 更新日期: 2023-09-27 18:18:33

我已经为用户创建了一个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>

我的所有地址数据模板将包含一个用于选择国家的组合框(名为"part_countryeslist")。我需要一些在选择更改时触发的代码隐藏操作,这意味着我需要挂钩SelectionChanged事件。在我的AddressInput中,我需要在AddressTemplate中找到part_countryeslist。

我可以得到"PART_AddressPresenter" ContentPresenter像这样:

public override void OnApplyTemplate()
{
    base.OnApplyTemplate();
    var addressPresenter = Template.FindName("PART_AddressPresenter", this) as ContentPresenter;
}

现在我如何得到"part_countryeslist"包含在AddressTemplate?

我试过了:

var countryeslist = AddressTemplate。FindName("PART_CountriesList",addressPresenter);

抛出异常,因为addressPresenter还没有应用它的模板。我知道ContentPresenter有OnApplyTemplate覆盖,但它似乎愚蠢的扩展它为这个用途。

我想如果我要扩展ContentPresenter,我会做一个新的可重用版本,每当OnApplyTemplate方法执行时触发一个事件。这可能会解决我的问题,但这似乎太疯狂了。有没有更好的办法?

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

我很好奇是否有人有"正确"的方法来做到这一点,但对于FindName,我总是最终诉诸于这样的东西:

Dispatcher.BeginInvoke( new Action(() =>
{
    // Call FindName here
}), System.Windows.Threading.DispatcherPriority.Render );

这可能会导致闪烁,因为你要等到数据模板完成并呈现之后再去执行你的代码,所以如果你想做的事情影响控件的外观,这并不总是一个好的选择。

相关文章:
  • 没有找到相关文章