wpf 如何在 ControlTemplate 中使用 ElementName 绑定?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15283039/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I use an ElementName binding within a ControlTemplate?
提问by Shawn Roser
I have multiple TextBlocks which reference different elements in my application. My code works fine when used directly in the page. However, I want to create a ControlTemplate and a ContentControl to reduce the duplication of code.
我有多个 TextBlock,它们引用了我的应用程序中的不同元素。当直接在页面中使用时,我的代码工作正常。但是,我想创建一个 ControlTemplate 和一个 ContentControl 以减少代码重复。
How can I pass a reference to an ElementName into the ControlTemplate from the ContentControl using TemplateBinding? The following code throws this error:
如何使用 TemplateBinding 将 ElementName 的引用从 ContentControl 传递到 ControlTemplate?以下代码抛出此错误:
"Cannot convert the value in attribute 'ElementName' to object of type 'System.String'. Object of type 'System.Windows.TemplateBindingExpression' cannot be converted to type 'System.String'. "
“无法将属性‘ElementName’中的值转换为‘System.String’类型的对象。‘System.Windows.TemplateBindingExpression’类型的对象无法转换为‘System.String’类型。”
In addition to the Tag attribute, I have tried ContentStringFormat which also did not work.
除了 Tag 属性之外,我还尝试了 ContentStringFormat ,但它也不起作用。
What is the correct method to get this to work using templates?
使用模板使其工作的正确方法是什么?
Thanks in advance for your help,
在此先感谢您的帮助,
--- Shawn
--- 肖恩
Here is the code sample:
这是代码示例:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<Page.Resources>
<ControlTemplate x:Key="MyTemplate" TargetType="{x:Type ContentControl}">
<TextBlock Margin="{Binding ElementName={TemplateBinding Tag}, Path=Margin}" Text="{TemplateBinding Content}" TextAlignment="{Binding ElementName={TemplateBinding Tag}, Path=TextAlignment}" Width="{Binding ElementName={TemplateBinding Tag}, Path=Width}" />
</ControlTemplate>
</Page.Resources>
<StackPanel>
<TextBlock x:Name="AnotherElement" Margin="10" Text="Main TextBlock" TextAlignment="Center" Width="100" />
<TextBlock x:Name="AnotherElement2" Margin="20" Text="Second TextBlock" TextAlignment="Left" Width="250" />
<TextBlock Margin="{Binding ElementName=AnotherElement, Path=Margin}" Text="Here is my TextBlock!" TextAlignment="{Binding ElementName=AnotherElement, Path=TextAlignment}" TextTrimming="CharacterEllipsis" Width="{Binding ElementName=AnotherElement, Path=Width}" />
<TextBlock Margin="{Binding ElementName=AnotherElement2, Path=Margin}" Text="Here is my Second TextBlock!" TextAlignment="{Binding ElementName=AnotherElement2, Path=TextAlignment}" TextTrimming="CharacterEllipsis" Width="{Binding ElementName=AnotherElement2, Path=Width}" />
<ContentControl Content="Hello!" Tag="AnotherElement" Template="{StaticResource MyTemplate}" />
<ContentControl Content="Hello Again!" Tag="AnotherElement2" Template="{StaticResource MyTemplate}" />
</StackPanel>
</Page>
回答by sa_ddam213
This seems like a funny way to template something, but it can be done, you just have to get a bit fancy with your bindings.
这似乎是一种对某些内容进行模板化的有趣方式,但它是可以做到的,您只需要对您的绑定有所了解。
The below will work, but I still dont think this is a good way to template a control
下面的将工作,但我仍然不认为这是模板控件的好方法
Bind the TextBlock
Tag
to the actual Element, then in the ControlTemplate
bind Tag
to Tag
and use the values from there as Tag is the Element, you can use any element from it.
将 绑定TextBlock
Tag
到实际元素,然后在ControlTemplate
绑定Tag
到Tag
并使用那里的值,因为 Tag 是元素,您可以使用其中的任何元素。
<Page.Resources>
<ControlTemplate x:Key="MyTemplate" TargetType="{x:Type ContentControl}">
<TextBlock Name="_this" Tag="{TemplateBinding Tag}" Margin="{Binding ElementName=_this, Path=Tag.Margin}" Text="{TemplateBinding Content}" TextAlignment="{Binding ElementName=_this, Path=Tag.TextAlignment}" Width="{Binding ElementName=_this, Path=Tag.Width}" />
</ControlTemplate>
</Page.Resources>
<StackPanel>
<TextBlock x:Name="AnotherElement" Margin="10" Text="Main TextBlock" TextAlignment="Center" Width="100" />
<TextBlock x:Name="AnotherElement2" Margin="20" Text="Second TextBlock" TextAlignment="Left" Width="250" />
<TextBlock Margin="{Binding ElementName=AnotherElement, Path=Margin}" Text="Here is my TextBlock!" TextAlignment="{Binding ElementName=AnotherElement, Path=TextAlignment}" TextTrimming="CharacterEllipsis" Width="{Binding ElementName=AnotherElement, Path=Width}" />
<TextBlock Margin="{Binding ElementName=AnotherElement2, Path=Margin}" Text="Here is my Second TextBlock!" TextAlignment="{Binding ElementName=AnotherElement2, Path=TextAlignment}" TextTrimming="CharacterEllipsis" Width="{Binding ElementName=AnotherElement2, Path=Width}" />
<ContentControl Content="Hello!" Tag="{Binding ElementName=AnotherElement}" Template="{StaticResource MyTemplate}" />
<ContentControl Content="Hello Again!" Tag="{Binding ElementName=AnotherElement2}" Template="{StaticResource MyTemplate}" />
</StackPanel>