我有一个非常奇怪和恼人的问题,我无法理解。这有点难以解释所以请耐心等待。
背景是我有一个有2个视图的应用程序,我可以在2之间来回切换。这是使用MVVM实现的,所以我有一个带有ContentControl的主窗口。 ContentControl的内容绑定到MainViewModel中的CurrentViewModel属性。 切换是通过使用命令绑定将CurrentViewModel设置为我的2个不同视图中的一个或另一个ViewModel。 2个ViewModel链接到App.xaml中的Views by DataTemplate定义。我相信这是一个相当常见的设置。 (注意,在当前实现中我使用MvvmLight并且ViewModel使用其SimpleIOC进行管理)
问题现在是如果我在一个视图中有一个ToggleButton,其中一些自定义内容(矩形和圆形)被绘制为切换/取消闭合状态。这是使用样式触发器(或DataTriggers)实现的。直到这里仍然没有问题,但如果我将Fill属性绑定到ToggleButton的前景颜色(请参阅下面的代码示例),会发生一些奇怪的事情:
修改 切换回时出的错误: System.Windows.Data错误:4:找不到引用'ElementName = TB1'的绑定源。 BindingExpression:路径=前景;的DataItem = NULL; target元素是'Ellipse'(Name =''); target属性为'Fill'(类型'Brush')
任何人都知道问题的来源以及如何解决这个问题? 我正在考虑简化测试应用程序,排除所有MvvmLight / IOC,但我怀疑这个问题与此有关。
<ToggleButton x:Name="TB1" Grid.Row="0" Grid.Column="1" Margin="5" Width="30"
Command="{Binding Toggle1}"
IsChecked="{Binding IsToggled1}">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Content" >
<Setter.Value>
<Rectangle Width="17" Height="17" Fill="{Binding ElementName=TB1, Path=Foreground}" />
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsToggled1}" Value="False">
<Setter Property="Content">
<Setter.Value>
<Ellipse Width="17" Height="17" Fill="{Binding ElementName=TB1, Path=Foreground}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
答案 0 :(得分:0)
您使用 XAML名称范围时遇到问题。它就像变量范围一样,仅适用于XAML名称。 XAML namescope是在XAML页面的根元素上创建的,但样式和模板有自己的名称范围,因为它们是可重用的。让我们说你的Style中的Rectangle或Ellipse有一个Name,你在视图中使用该样式有5个ToggleButtons。如果Styles没有自己的名称范围,那么在同一个名称范围内将有5个具有相同名称的元素。 解析XAML时,将应用其中一个Content属性值(取决于ToggleButton的IsChecked状态)。它进入TogglButton的名称范围并且ElementName被解析,但是另一个仍然在名称范围之外并且无法解析。
那你能做什么?您可以使用x:Reference
标记扩展名。因此,您可以使用ElementName=TB1
代替Source={x:Reference TB1}
。但是然后XAML解析器会抛出一个循环依赖异常,因为你的引用会指向一个包含引用的元素(你的Style在你的ToggleButton中定义)。要解决此问题,请将您的样式定义为资源:
<Window.Resources>
<Style x:key="TBStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Content">
<Setter.Value>
<Rectangle Width="17" Height="17"
Fill="{Binding Foreground, Source={x:Reference TB1}}"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding IsToggled1}" Value="False">
<Setter Property="Content">
<Setter.Value>
<Ellipse Width="17" Height="17"
Fill="{Binding Foreground, Source={x:Reference TB1}}}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
....
<ToggleButton x:Name="TB1"
Margin="5"
Width="30"
Height="30"
IsChecked="{Binding IsToggled1}"
Style="{StaticResource TBStyle}"/>
如果您将此样式应用于5个ToggleButtons,它们都会从名为&#34; TB1&#34;的一个按钮中选择前景颜色,但这是完全不同的问题。