触发的数据触发器未更改自定义控件的 属性(ControlTemplate)

Fired datatrigger is not changing custom control's property(ControlTemplate)

我想更改 CustomControl 中的 DependcyProperty(命名为 MessageTemplateProperty),类型为 Controltemplate

但我无法使用 datatrigger

为其设置值

但是CustomControl中的另一个DependcyProperty(命名为IsShowMessageProperty)类型是bool可以使用datatrigger设置。

谁能解释一下,为什么,如何解决。

自定义代码如下:

public class MessageOverLay : ContentControl
{
    static MessageOverLay()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MessageOverLay),
            new FrameworkPropertyMetadata(typeof(MessageOverLay)));
    }

    #region DependcyProperties

    // Template attached property

    public static readonly DependencyProperty MessageTemplateProperty =
        DependencyProperty.Register("MessageTemplate", typeof(ControlTemplate), typeof(MessageOverLay),
            new FrameworkPropertyMetadata(MessageTemplateChanged));

    public ControlTemplate MessageTemplate
    {
        set{SetValue(MessageTemplateProperty, value);}
        get{return (ControlTemplate)GetValue(MessageTemplateProperty);}
     }

    // IsVisible attached property

    public static readonly DependencyProperty IsShowMessageProperty =
        DependencyProperty.Register("IsShowMessage", typeof(bool), typeof(MessageOverLay),
            new PropertyMetadata(IsShowMessageChanged));

    public bool IsShowMessage
    {
        get{return (bool)GetValue(IsShowMessageProperty);}
        set{SetValue(IsShowMessageProperty, value);}
    }


    #endregion DependcyProperties



}

自定义默认主题Generic.xaml

 <Style TargetType="{x:Type controls:MessageOverLay}">
      <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="controls:MessageOverLay">
                <AdornerDecorator>
                    <Grid>
                        <ContentPresenter  x:Name="PART_Conent"
                                        VerticalAlignment="Stretch"
                                        HorizontalAlignment="Stretch"

                                         Content="{TemplateBinding Content}" />
                        <Control x:Name="Part_MessageControl" Template="{TemplateBinding MessageTemplate}" 
                                 Visibility="{TemplateBinding IsShowMessage,Converter={StaticResource BooleanToVisibilityConverter}}" />
                    </Grid>
                </AdornerDecorator>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="MessageTemplate">
        <Setter.Value>
            <ControlTemplate>
                <Grid HorizontalAlignment="Left" VerticalAlignment="Bottom">
                    <Grid Width="150" Height="100" Margin="5  0 0 10">
                        <Rectangle Stroke="Black" Fill="Yellow" RadiusX="6" RadiusY="6" Margin="0 20 0 0" />
                        <TextBlock Text="What are you doing?" Margin="5 25 0 0" />
                        <Button Content="Cancel" Margin="5" VerticalAlignment="Bottom" HorizontalAlignment="Right" />
                        <Button Content="OK" Margin="5" VerticalAlignment="Bottom" HorizontalAlignment="Left" />
                    </Grid>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我想按如下方式使用它:

演示 XAML:

  <Window ...>
<Window.Resources>
    <ControlTemplate x:Key="GenderPopupTemplate">
        <Grid HorizontalAlignment="Left" VerticalAlignment="Bottom">
            <Grid Width="200" Height="100" Margin=" 5 0 0 10">              
                <TextBlock Text="Please Select Gender " Margin="5 25 0 0" />
                <Button Content="Male" Margin="5" VerticalAlignment="Bottom" HorizontalAlignment="Left"
                        Command="{Binding SelectedGenderCommand}" />
                <Button Content="FeMale" Margin="5" VerticalAlignment="Bottom" HorizontalAlignment="Right"
                        Command="{Binding SelectedGenderCommand}" />
            </Grid>
        </Grid>
    </ControlTemplate>

    <ControlTemplate x:Key="FacePopupTemplate">
        <Grid HorizontalAlignment="Left" VerticalAlignment="Bottom">
            <Grid Width="200" Height="100" Margin="5 10 0 0">
                <TextBlock Text="Do you like your Face,Now?" Margin="5 25 0 0" />
                <Button Content="OK" Margin="5" VerticalAlignment="Bottom" HorizontalAlignment="Left"
                        Command="{Binding OKCommand}" />
            </Grid>
        </Grid>
    </ControlTemplate>
</Window.Resources>

    <controls:MessageOverLay  HorizontalAlignment="Stretch"
                              VerticalAlignment="Stretch"
                              MessageTemplate="{StaticResource GenderPopupTemplate}"
                             IsShowMessage="True">
        <controls:MessageOverLay.Style>
            <Style TargetType="{x:Type controls:MessageOverLay}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding MessageBoxType}" Value="{x:Static viewModels:MessageBoxTypes.SelectView}">
                        <Setter Property="MessageTemplate" Value="{StaticResource GenderPopupTemplate}"></Setter>
                        <Setter Property="Height" Value="350"/>
                    </DataTrigger>
                    <DataTrigger Binding="{Binding MessageBoxType}" Value="{x:Static viewModels:MessageBoxTypes.MessageView}">
                        <Setter Property="MessageTemplate" Value="{StaticResource FacePopupTemplate}"></Setter>
                        <Setter Property="Height" Value="150"/>
                    </DataTrigger>

                </Style.Triggers>
            </Style>
        </controls:MessageOverLay.Style>
        <Grid  Background="SeaGreen" 
               HorizontalAlignment="Stretch"
                              VerticalAlignment="Stretch">
            <TextBlock Text="Content"/>
        </Grid>
    </controls:MessageOverLay>

我想在 MainWindowViewModel 的 属性 MessageBoxType 更改时更改 MessageTemplate。 但是我不能存档。

其他相关代码

演示 C# 代码:

public class MainWindowViewModel : BindableBase
{
    public ICommand SelectedGenderCommand { get; }

    public ICommand OKCommand { get; }

    private MessageBoxTypes _messageBoxType;

    public MessageBoxTypes MessageBoxType
    {
        get { return _messageBoxType; }
        set { SetProperty(ref _messageBoxType, value); }
    }

    private string _title = "Prism Unity Application";

    public string Title
    {
        get { return _title; }
        set { SetProperty(ref _title, value); }
    }

    public MainWindowViewModel()
    {
        MessageBoxType = MessageBoxTypes.SelectView;

        SelectedGenderCommand = new DelegateCommand<object>(SelectedGender);

        OKCommand = new DelegateCommand<object>(OK);
    }

    private void OK(object obj)
    {
        MessageBoxType = MessageBoxTypes.SelectView;
    }

    private void SelectedGender(object obj)
    {
        MessageBoxType = MessageBoxTypes.MessageView;
    }
}

public enum MessageBoxTypes
{
    SelectView,
    MessageView,
    ConfirmView
}

更新:

Here是github中的完整演示代码,请查看

当样式 Setter 设置依赖项 属性 时,不能像在

中那样直接分配所谓的本地值
<controls:MessageOverLay MessageTemplate="{StaticResource GenderPopupTemplate}" ...>

直接分配的本地值总是比样式 Setters(和其他可能的来源)中的任何值具有更高的优先级,因此 Setter 无效。可以在此处找到更多详细信息:Dependency Property Value Precedence.

将直接分配替换为另一种样式Setter:

 <controls:MessageOverLay  ...>
    <controls:MessageOverLay.Style>
        <Style TargetType="{x:Type controls:MessageOverLay}">

            <Setter Property="MessageTemplate"
                    Value="{StaticResource GenderPopupTemplate}"/>

            <Style.Triggers>
                ...
            </Style.Triggers>
        </Style>
    </controls:MessageOverLay.Style>
    ...
</controls:MessageOverLay>