WPF:从 DataTemplate 修改 ControlTemplate 属性?
使用 WPF 的 MVVM 方法,我有一个名为 SubButton
的视图模型类。它的样式如下:
<!-- SubNavButton Appearance -->
<ControlTemplate x:Key="SubNavButton" TargetType="{x:Type RadioButton}">
<Grid Margin="5,5">
<Rectangle x:Name="rectBackground" Fill="DimGray" Stroke="#FF000000" Width="150" Height="40" StrokeThickness="1"/>
<TextBlock x:Name="txtContent" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Arial" FontSize="16">
<ContentPresenter />
</TextBlock>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" TargetName="rectBackground" Value="Red"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Fill" TargetName="rectBackground" Value="Pink"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- SubButton data template -->
<DataTemplate DataType="{x:Type VM:SubButton}">
<RadioButton
Template="{StaticResource SubNavButton}"
Content="{Binding TempText}"
Command="{Binding SubFrameChanger.Command}"
CommandParameter="{Binding Key}"
GroupName="{Binding MenuGroup}"
V:CreateCommandBinding.Command="{Binding SubFrameChanger}" />
<DataTemplate.Triggers>
<!-- This trigger doesn't work -->
<DataTrigger Binding="{Binding Path=Selected}" Value="True">
<Setter TargetName="rectBackground" Property="Fill" Value="Green"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
DataTrigger
不起作用。 Selected
是 SubButton
类上的常规 .Net 属性。我收到编译错误,因为编译器无法确定 rectBackground
目标来自何处。它是 ControlTemplate
的一部分,我不知道如何告诉它?有关 DataContext
的信息吗?
Using an MVVM approach to WPF, I have a view model class called SubButton
. It is styled as follows:
<!-- SubNavButton Appearance -->
<ControlTemplate x:Key="SubNavButton" TargetType="{x:Type RadioButton}">
<Grid Margin="5,5">
<Rectangle x:Name="rectBackground" Fill="DimGray" Stroke="#FF000000" Width="150" Height="40" StrokeThickness="1"/>
<TextBlock x:Name="txtContent" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Arial" FontSize="16">
<ContentPresenter />
</TextBlock>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Fill" TargetName="rectBackground" Value="Red"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Fill" TargetName="rectBackground" Value="Pink"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- SubButton data template -->
<DataTemplate DataType="{x:Type VM:SubButton}">
<RadioButton
Template="{StaticResource SubNavButton}"
Content="{Binding TempText}"
Command="{Binding SubFrameChanger.Command}"
CommandParameter="{Binding Key}"
GroupName="{Binding MenuGroup}"
V:CreateCommandBinding.Command="{Binding SubFrameChanger}" />
<DataTemplate.Triggers>
<!-- This trigger doesn't work -->
<DataTrigger Binding="{Binding Path=Selected}" Value="True">
<Setter TargetName="rectBackground" Property="Fill" Value="Green"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
The DataTrigger
doesn't work. Selected
is a regular .Net property on the SubButton
class. I am getting a compilation error because the compiler can't figure out where the rectBackground
target comes from. It is part of the ControlTemplate
, I'm not sure how to tell it that? Something about the DataContext
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你想要的东西是不可能的。 WPF 使用 NameScopes,并且名称 rectBackground 超出了 DataTemplate 的范围。原始名称 rectBackground 将仅在原始 ControlTemplate 内的范围内。这是幸运的,因为否则您将无法在整个应用程序中使用重复的名称。
您可以做的就是通过 TemplateBinding 将 rectBackground 的 Fill 属性绑定到 RadioButton 的 Background 属性。当您在代码中的其他任何位置更改 RadioButton 的背景时, rectBackground 将获取此画笔作为其填充。我稍微修改了你的代码来说明这一点。使用 DataTemplate 可以轻松地将其更改为您的模型。
What you want is not possible. WPF works with NameScopes and the name rectBackground is out of scope in the DataTemplate. The original name rectBackground will only be in scope inside the original ControlTemplate. This is fortunate, because otherwise you would not be able to use a duplicate name throughout your entire application.
What you can do is bind the Fill property of rectBackground to the RadioButton's Background property through TemplateBinding. When you change the RadioButton's Background anywhere else in your code rectBackground will get this Brush as its Fill. I modified your code somewhat to illustrate the point. It will be easy to change this to your model with a DataTemplate.