【问题标题】:WPF: Modifying a ControlTemplate property from a DataTemplate?WPF:从 DataTemplate 修改 ControlTemplate 属性?
【发布时间】:2009-11-29 17:39:21
【问题描述】:

对 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 不起作用。 SelectedSubButton 类的常规 .Net 属性。我收到编译错误,因为编译器无法确定 rectBackground 目标的来源。它是ControlTemplate 的一部分,我不知道该怎么说?关于DataContext 的事情?

【问题讨论】:

    标签: c# .net wpf datatemplate controltemplate


    【解决方案1】:

    你想要的都是不可能的。 WPF 与 NameScopes 一起使用,并且名称 rectBackground 超出了 DataTemplate 的范围。原始名称 rectBackground 将仅在原始 ControlTemplate 的范围内。这是幸运的,否则您将无法在整个应用程序中使用重复的名称。 您可以做的是通过 TemplateBinding 将 rectBackground 的 Fill 属性绑定到 RadioButton 的 Background 属性。当您在代码中的任何其他位置更改 RadioButton 的背景时,rectBackground 将获得此 Brush 作为其填充。我稍微修改了您的代码以说明这一点。使用 DataTemplate 很容易将其更改为您的模型。

        <Window.Resources>
            <ControlTemplate x:Key="SubNavButton" TargetType="RadioButton">
                <Grid Margin="5,5">
                    <Rectangle x:Name="rectBackground"
                           Fill="{TemplateBinding Background}" 
                           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>
            <!-- The Style simulates the same behavior as the DataTemplate-->
            <Style TargetType="RadioButton">
                <Setter Property="Template" 
                    Value="{StaticResource SubNavButton}"/>
                <Style.Triggers>
                    <Trigger Property="IsFocused" Value="True">
                        <Setter Property="Background" Value="Green"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Window.Resources>
        <StackPanel>
           <RadioButton>one</RadioButton>
           <RadioButton>two</RadioButton>
        </StackPanel> 
    

    【讨论】:

    • 谢谢,TemplateBinding 更有意义,我想知道“外部世界”的东西是如何进入控件的 :) 但是 DataTrigger 仍然无法工作......
    • 我认为这没有正确设置 IsChecked (应该改变背景颜色):
    • 它在我的示例中有效:只需更改样式触发器中的设置器。问题必须在绑定的 Selected 属性中。它是否正确实现了更改通知?
    • 我在我删除的评论中出去吃午饭了...你完全正确,谢谢! :)
    • 我的示例可以重写以设置 IsChecked 而不是背景。 rectBackground 然后变成粉红色。
    猜你喜欢
    • 2010-12-17
    • 2013-04-26
    • 2022-08-17
    • 2015-04-20
    • 2023-01-16
    • 2016-01-11
    • 2016-05-06
    • 2011-03-08
    • 2010-10-16
    相关资源
    最近更新 更多