Как найти элемент в DataTemplate, примененный к ContentPresenter? - PullRequest
0 голосов
/ 22 декабря 2011

Я создал элемент управления AddressInput для пользователей, чтобы ввести адрес. Элемент управления будет выглядеть по-разному в зависимости от того, где он используется, поэтому я предоставил свойство DataTemplate под названием AddressTemplate.

Стиль по умолчанию выглядит следующим образом:

<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_CountriesList"). Мне нужно иметь какое-то кодовое действие, которое срабатывает при изменении выделения, а это значит, что мне нужно перехватить событие SelectionChanged. Внутри моего AddressInput мне нужно найти PART_CountriesList в AddressTemplate.

Я могу получить ContentPresenter "PART_AddressPresenter" следующим образом:

public override void OnApplyTemplate()
{
    base.OnApplyTemplate();

    var addressPresenter = Template.FindName("PART_AddressPresenter", this) as ContentPresenter;
}

Теперь, как мне получить "PART_CountriesList", содержащийся в AddressTemplate?

Я пробовал это:

var countryList = AddressTemplate.FindName ("PART_CountriesList", addressPresenter);

Исключение выдается, потому что для addressPresenter еще не применен шаблон. Я знаю, что ContentPresenter имеет переопределение OnApplyTemplate, но кажется глупым расширять его для этого использования.

Полагаю, если бы я расширил ContentPresenter, я сделал бы новую версию для повторного использования, которая запускает событие всякий раз, когда выполняется метод OnApplyTemplate. Это, вероятно, решило бы мою проблему, но это кажется сумасшедшим. Есть ли лучший способ?

1 Ответ

0 голосов
/ 22 декабря 2011

Мне любопытно, если у кого-то есть «правильный» способ сделать это, но с FindName я всегда заканчиваю тем, что прибегаю к чему-то вроде этого:

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

Это может вызвать мерцание, потому что выподождать, пока шаблонирование данных не будет выполнено и обработано, чтобы выполнить ваш код, поэтому, если то, что вы пытаетесь сделать, влияет на внешний вид элемента управления, это не всегда хороший вариант.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...