触发的数据触发器没有改变自定义控件的属性(ControlTemplate)

本文关键字:属性 自定义控件 ControlTemplate 改变 数据 触发器 | 更新日期: 2023-09-27 18:13:45

我想改变一个DependcyProperty(Named is as MessageTemplateProperty),这是在CustomControl和类型是Controltemplate

但是我不能设置它的值使用datatrigger

但是另一个DependcyProperty(命名为IsShowMessageProperty)是在CustomControl和类型是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
}
更新:

这里是完整的演示代码在github,请检查它

触发的数据触发器没有改变自定义控件的属性(ControlTemplate)

当Style Setter要设置依赖属性时,必须不像在

中那样直接赋值所谓的局部值。
<controls:MessageOverLay MessageTemplate="{StaticResource GenderPopupTemplate}" ...>

直接赋值的局部值总是比来自Style Setter(和其他可能的来源)的任何值具有更高的优先级,因此Setter没有作用。更多细节可以在这里找到:依赖属性值优先级。

用另一个Style 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>