简体   繁体   English

WPF:修改DataTemplate的ControlTemplate属性?

[英]WPF: Modifying a ControlTemplate property from a DataTemplate?

Using an MVVM approach to WPF, I have a view model class called SubButton . 使用MVVM方法来实现WPF,我有一个名为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. DataTrigger不起作用。 Selected is a regular .Net property on the SubButton class. SelectedSubButton类上的常规.Net属性。 I am getting a compilation error because the compiler can't figure out where the rectBackground target comes from. 我收到一个编译错误,因为编译器无法确定rectBackground目标的来源。 It is part of the ControlTemplate , I'm not sure how to tell it that? 它是ControlTemplate一部分,我不确定如何告诉它? Something about the DataContext ? 关于DataContext东西?

What you want is not possible. 您想要的是不可能的。 WPF works with NameScopes and the name rectBackground is out of scope in the DataTemplate. WPF与NameScopes一起使用,名称rectBackground在DataTemplate中超出范围。 The original name rectBackground will only be in scope inside the original ControlTemplate. 原始名称rectBackground将仅在原始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. 您可以做的是通过TemplateBinding将rectBackground的Fill属性绑定到RadioButton的Background属性。 When you change the RadioButton's Background anywhere else in your code rectBackground will get this Brush as its Fill. 当您在代码中的其他任何地方更改RadioButton的Background时,rectBackground都会将此笔刷作为其Fill。 I modified your code somewhat to illustrate the point. 我对您的代码做了一些修改以说明这一点。 It will be easy to change this to your model with a DataTemplate. 使用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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM