Элемент доступа внутри Silverlight DataTemplate - PullRequest
5 голосов
/ 10 августа 2010

Мне не удалось найти чистое решение для следующей проблемы, хотя в SO уже есть несколько связанных вопросов.

Если у меня есть шаблон данных, который используется, например, несколько раз, напримерTreeViewItem.HeaderTemplate, как я могу что-то изменить шаблон только для некоторых TreeViewItems.

Например, предположим, что мой TVI HeaderTemplate имеет текстовый блок и в зависимости от строки я хочу сделать жирный шрифт жирным шрифтом.

Я хочу сделать что-то подобное:

((TextBlock)myTreeView.Items.ElementAt(0).FindName("myTextBlock")).FontWeight = FontWeights.Bold;

У кого-нибудь есть решение для этого?-> Спасибо, Эван

Редактировать: Есть ли способ написать универсальную функцию для получения элемента управления на основе его имени, даже если он находится в шаблоне данных?

LayoutRoot.FindName("myTextBlock"); сработало бы, если бы myTextBlock не было в табличке данных.Как я могу написать функцию findElementInDataTemplate(string elementName, string parentName)?

Причина, по которой Эван отвечает не тем, что я ищу, заключается в том, что я разрабатываю элемент управления.Я хочу, чтобы разработчик приложения, использующий мой элемент управления, мог изменять любой элемент элемента управления.Если я использую решение Эвана, это потребует от разработчика приложения доступа ко всем шаблонам в элементе управления.Возможно, но не идеально.Спасибо!

Ответы [ 5 ]

4 голосов
/ 10 августа 2010

Один из способов сделать это - сохранить все необходимые элементы в переменной коллекции уровня класса с помощью события Loaded элемента управления.Возьмем, к примеру, этот DataTemplate.

<DataTemplate>
   ...
   <TextBlock Loaded="TemplateTextBlock_Loaded" />
</DataTemplate>

Затем вы используете событие Loaded для загрузки какой-либо коллекции для последующего использования.

private List<TextBlock> templateTextBlocks = new List<TextBlock>();

private void TemplateTextBlock_Loaded(object sender, RoutedEventArgs e)
{
   TextBlock tb = sender as TextBlock;
   if (!this.templateTextBlocks.Contains(tb)) this.templateTextBlocks.Add(tb);
}

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

2 голосов
/ 10 августа 2010

Если вы используете привязку данных, пробовали ли вы использовать конвертер привязок?В этом случае вы бы сделали что-то вроде ...

FontWeight={Binding Path=TextProperty, Converter={StaticResource BoldConverter}}

И конвертер будет выглядеть следующим образом ...

string myTestString = (string)value;
if (myTestString.Contains("Bob"))
    return FontWeights.Bold;
return FontWeights.Normal;

Что делает его менее болезненным, чтобы попытаться получить root правачерез элементы, чтобы найти конкретный.

1 голос
/ 10 августа 2010

Моя первая реакция на такое требование: вы действительно уверены, что хотите это сделать?Обычно я призываю разработчиков взглянуть на существующие шаблоны управления.В этом случае то, что вам кажется шаблонным элементом управления, может показаться оправданным.

Конечно, это не обеспечивает гибкость, к которой вы стремитесь.Похоже, что после вас возникает «святой Грааль» настраиваемых элементов управления, стремление откорректировать любые незначительные детали элемента управления без необходимости дублирования всего шаблона элемента управления.Конечно, это не совсем возможно декларативно, если бы я боялся синтаксиса и семантических правил, которые бы управляли им.

Сказав, что всегда есть исключения.Поэтому я представлю возможный вариант, несмотря на то, что вам не следует этого делать.

Этот старый ответ предоставляет метод расширения Descendents, позволяющий перечислять элементы управления в дереве объектов.,Если у вас есть экземпляр TreeViewItem, вы сможете найти TextBlock, который вам нужен, с помощью: -

TextBlock tb = treeViewItem.Descendents()
                 .OfType<TextBlock>()
                 .Where(t => t.Name == "myTextBlock")
                 .FirstOrDefault();
0 голосов
/ 26 июля 2011

также можете попробовать это

TextBlock txtBlk = grd.FindName ("txtBlkName") как TextBlock;

где grd = ваш корневой элемент (родительский элемент элемента, который вы ищете) ** 1005

0 голосов
/ 21 декабря 2010

какая версия silverlight это?И с какого года "10 августа в 18:55" это сообщение?

в текущей версии SL4, похоже, его там нет ...

...