Программный доступ к элементу управления из DataTemplate
Какой хороший способ получить доступ к элементам управления в DataTemplate? Я использовал технику обработки события Loaded для элемента управления, представляющего интерес, а также использовал VisualTreeHelper для обхода дерева визуалов, и ни один из них не является очень элегантным. Какой хороший способ получить доступ к элементам управления DataTemplate?
В одном примере мне нужно добавить привязку, которую ConverterParameter не знает во время разработки, и поскольку привязка к ConverterParameter не поддерживается, мне нужно создать привязку в коде. В идеале я хотел бы иметь возможность сделать это где-нибудь кроме обработчика событий Loaded для элемента управления в табличке данных.
Фактически, в этом сценарии обработка событий вообще не работает и вызывает исключение OutOfMemoryException. Вот моя попытка:
Generic.xaml:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SilverlightTest">
<Style TargetType="local:TemplatedControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TemplatedControl">
<ListBox ItemsSource="{TemplateBinding ListBoxItemsSource}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="SomeTextBlock"
Loaded="SomeTextBlock_Loaded"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
templatedcontrol.cs:
public class TemplatedControl : Control
{
public object ListBoxItemsSource
{
get { return (object)GetValue(ListBoxItemsSourceProperty); }
set { SetValue(ListBoxItemsSourceProperty, value); }
}
public static readonly DependencyProperty ListBoxItemsSourceProperty =
DependencyProperty.Register
("ListBoxItemsSource", typeof(object),
typeof(TemplatedControl), new PropertyMetadata(null));
public TemplatedControl()
{
this.DefaultStyleKey = typeof(TemplatedControl);
}
public void SomeTextBlock_Loaded(object sender, RoutedEventArgs ea)
{
}
}
1 ответ
У вас может быть другой элемент управления в вашем DataTemplate, чтобы справиться с этим, но это немного запутанно и с оговоркой "если вы действительно не верите, что логика оправдывает это".
Возможно, вы захотите переосмыслить свой подход. На мой взгляд (и это просто мнение!), Код должен связывать код только в более экзотических ситуациях.
Возможно, вместо использования IValueConverter, свяжите со свойством в ViewModel (предполагая, что ваш ItemsSource является коллекцией ViewModels), и позвольте вашей виртуальной машине соответствующим образом преобразовать ваши значения. Позвольте вашему стилю по умолчанию для этого элемента управления быть универсальным и уродливым и, возможно, использовать определенные стили для случаев, когда вам нужно привязать к определенным свойствам.