即使在SO上已经存在一些相关问题,我也无法找到以下问题的干净解决方案。
如果我有一个多次使用的数据模板,例如TreeViewItem.HeaderTemplate,我该如何更改某些TreeViewItems的模板。
例如,假设我的TVI HeaderTemplate有一个文本块,根据字符串,我想使字体粗体。
我想做这样的事情:
((TextBlock)myTreeView.Items.ElementAt(0).FindName("myTextBlock")).FontWeight = FontWeights.Bold;
有人有解决方案吗? - >谢谢埃文
编辑:有没有办法编写一个通用函数来获取基于它的名称的控件,即使它在数据模板中?
如果myTextBlock不在datatemplate中, LayoutRoot.FindName("myTextBlock");
将起作用。如何编写findElementInDataTemplate(string elementName, string parentName)
函数?
Evan的答案不是我正在寻找的原因是因为我正在开发一个控件。我希望使用我的控件的应用程序开发人员能够更改控件中的任何元素。如果我使用Evan的解决方案,则需要应用程序开发人员访问控件中的所有模板。可能,但不理想。谢谢!
答案 0 :(得分:4)
我实现此目的的一种方法是使用控件的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);
}
当然,如果您要加载和卸载控件,这可能不适合您。
答案 1 :(得分:2)
如果您正在使用数据绑定,您是否尝试过使用绑定转换器?在这种情况下,你会做类似......
的事情FontWeight={Binding Path=TextProperty, Converter={StaticResource BoldConverter}}
转换器将沿着......
string myTestString = (string)value;
if (myTestString.Contains("Bob"))
return FontWeights.Bold;
return FontWeights.Normal;
这使得尝试通过元素定位特定的元素变得不那么痛苦。
答案 2 :(得分:1)
我对这种要求的第一反应是:你真的确定要这么做吗?我通常会敦促开发人员查看正在使用的现有控件模式。在这种情况下,你似乎是模板控制似乎是有道理的。
当然,这并不能提供您所追求的灵活性。您似乎追求的是可自定义控件的“圣杯”,希望调整控件的任何细节,而不必复制整个控件模板。当然,如果我害怕会控制它的语法和语义规则,那么这在声明上是不可能实现的。
说过总有例外。所以我会提出一个可能的选择,尽管你不应该这样做。
这个旧的answer提供了Descendents
扩展方法,允许您枚举对象树中的控件。给定TreeViewItem
的实例,您应该能够找到您所追求的TextBlock
: -
TextBlock tb = treeViewItem.Descendents()
.OfType<TextBlock>()
.Where(t => t.Name == "myTextBlock")
.FirstOrDefault();
答案 3 :(得分:0)
这是什么版本的silverlight? 那个“8月10日18:55”的这一年的帖子是什么?
在当前版本的SL4中似乎没有......
答案 4 :(得分:0)
也可以试试这个
TextBlock txtBlk = grd.FindName(“txtBlkName”)as TextBlock;
其中grd =您的根元素(您要查找的元素的父元素)