Access Element inside Silverlight DataTemplate

北慕城南 提交于 2019-12-10 05:05:38

问题


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!


回答1:


what version of silverlight is this? And what year of " Aug 10 at 18:55" is this post from?

in the current version of SL4 it does not seem to be there..




回答2:


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.




回答3:


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.




回答4:


My first reaction to such a requirement would be: are you really sure you want to be doing that? I would normally urge developers to look at the existing control patterns being used. In this case what you seem a Templated control would seem warranted.

Of course this doesn't provide the flexibility you are after. What you seem to be after is the "holy grail" of customisable controls, the desire to tweak any minor detail about the control without having to duplicate the entire template of the control. OF course this isn't really possible declaratively, if it were I'd dread the syntax and semantic rules that would govern it.

Having said that there are always exceptions. So I'll present a possible option despite feeling that you shouldn't be doing this.

This old answer provides a Descendents extension method allow you to enumerate controls across the object tree. Given an instance of a TreeViewItem you should be able to find the TextBlock you are after with:-

TextBlock tb = treeViewItem.Descendents()
                 .OfType<TextBlock>()
                 .Where(t => t.Name == "myTextBlock")
                 .FirstOrDefault();



回答5:


can also try this

TextBlock txtBlk = grd.FindName("txtBlkName") as TextBlock;

where grd = your root element (Parent of the element you are looking for)



来源:https://stackoverflow.com/questions/3450607/access-element-inside-silverlight-datatemplate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!