Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access Element inside Silverlight DataTemplate

I have not been able to find a clean solution to the following problem even though there are a few related questions already on SO.

If I have a data template that is being used multiple times, for example, a TreeViewItem.HeaderTemplate, how can I change something the template for only some of the TreeViewItems.

For example, let's say my TVI HeaderTemplate has a textblock and depending on the string, I want to make the fontweight bold.

I want to do something like this:

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

Does anyone have a solution for this? --> Thanks Evan

Edit: Is there a way to write a generic function to get a control based on it's name even if it's in a data template?

LayoutRoot.FindName("myTextBlock"); would work if myTextBlock was not in a datatemplate. How can I write a findElementInDataTemplate(string elementName, string parentName) function?

The reason Evan's answer is not what I'm looking for is because I am developing a control. I want the application developer who uses my control to be able to change any element in the control. If I use Evan's solution, that would require the application developer to have access to all the templates in the control. Possible, but not ideal. Thanks!

like image 880
NickHalden Avatar asked Aug 10 '10 15:08

NickHalden


2 Answers

One way I have accomplished this is to store all the needed items in a class-level collection variable by using the Loaded event of the control. Take this DataTemplate for example.

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

Then you use the Loaded event to load up some sort of collection for later use.

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);
}

Of course, if you're going to be loading and unloading the control, this may not work well for you.

like image 77
Steve Danner Avatar answered Sep 18 '22 20:09

Steve Danner


If you're using data binding, have you tried using a binding converter? In this case you would do something like...

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

And the converter would be along the lines of...

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

Which makes it less painful to try and root through the elements to locate a particular one.

like image 27
Evan Hutnick Avatar answered Sep 19 '22 20:09

Evan Hutnick