I’ve created an AddressInput control for users to enter an address. The control will have a different look depending on where it’s used, so I provided a DataTemplate property called AddressTemplate.
The default style looks like this:
<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>
All of my address data templates will contain a combo box for selecting the country (named “PART_CountriesList”). I need to have some code-behind action that fires when the selection changes, which means I need to hook the SelectionChanged event. Inside my AddressInput I need to find PART_CountriesList in the AddressTemplate.
I can get the “PART_AddressPresenter” ContentPresenter like this:
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var addressPresenter = Template.FindName("PART_AddressPresenter", this) as ContentPresenter;
}
Now how do I get “PART_CountriesList” contained inside AddressTemplate?
I tried this:
var countriesList = AddressTemplate.FindName(“PART_CountriesList”, addressPresenter);
An exception is thrown because addressPresenter hasn’t had its template applied yet. I know ContentPresenter has the OnApplyTemplate override, but it seems silly to extend it for this use.
I suppose if I were to extend ContentPresenter, I’d make a new reusable version that fires an event whenever the OnApplyTemplate method executes. This would probably solve my problem, but it seems crazy. Is there a better way?
I’m curious if someone has the “right” way to do this, but with FindName I always end up resorting to something like this:
This can cause flicker though because you’re waiting until after the data templating is done and rendered to go exercise your code, so if what you’re trying to do affects the look of the control this isn’t always a great option.