2013-03-07 74 views
11

我有多个TextBlocks在我的应用程序中引用不同的元素。我的代码直接在页面中使用时工作正常。不过,我想创建一个ControlTemplate和一个ContentControl来减少代码的重复。如何使用ControlTemplate中的ElementName绑定?

如何将使用TemplateBinding的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'. "

除了Tag属性之外,我尝试了ContentStringFormat,它也没有工作。

什么是正确的方法来使它使用模板?

预先感谢您的帮助,

---肖恩

下面是代码示例:

<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> 
+1

为什么不创建样式并将其应用于所有需要该样式的控件?为什么要在一个控件上定义一些属性,然后将其他控件绑定到它?这听起来很奇怪。 – 2013-03-07 23:25:13

+0

@Brent将信息存储在Tag属性中,曾经是MS Access表单开发的技术。将一些硬编码值传递给绑定到您控件上的某个属性/处理函数的VBA函数是一种便宜而又糟糕的方式。我们不需要WPF,因为我们有更多的工具可供我们使用=) – failedprogramming 2013-03-08 08:17:48

+0

@BrentStewart该实现的最终结果是使用MVVM,Bindings,DataTemplates等在列中显示信息。我特意缩小了我的示例在这个网站上询问。我选择不使用Grid,而是使用WrapPanel,因为我觉得使用它更简单,更清洁。我将一个TextBlock的几个属性绑定到另一个是因为我希望我的列值复制我为其特定标题(边距,宽度,对齐方式等)设置的属性。你将如何实现这个使用样式时,每个文本块它会引用一个不同的元素名称? – 2013-03-08 16:18:01

回答

23

这似乎是一个有趣的方式到模板的东西,但它可以是完成后,你只需要对你的绑定有点想象。

下面的工作,但我仍然不认为这是模板控制

绑定的好方法TextBlockTag实际的元素,然后在ControlTemplate绑定TagTag,并从那里使用的值作为标签是元素,你可以使用它的任何元素。

<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> 
+2

+1表示这不是模板控件的好方法。 – 2013-03-07 23:26:05

+14

谢谢你的回答。这在我的应用程序中正常工作。你和@BrentStewart都表示这不是模板化控件的好方法。在你的选择中,什么是一个好方法,为什么这不是一个? – 2013-03-08 16:20:37

+3

是的,没有其他选择,所以它的愚蠢说“它不是一个好办法”。显然,但还有哪些其他选项可用?由于视觉树的设计方式,这种限制经常出现。 – user99999991 2016-09-01 22:00:45

相关问题