MultiTigger 绑定异常处理

简介: 原文:MultiTigger 绑定异常处理异常产生环境: 在初始化一个窗口后,没有show出来。在此窗口中,有个控件,重写了控件模板,并加了MultiTrigger。 注意:俩个Condition,一个是从外面绑定过来的Tag,一个是ControlTemplate中Element的属性Tag。
原文: MultiTigger 绑定异常处理

异常产生环境:

在初始化一个窗口后,没有show出来。在此窗口中,有个控件,重写了控件模板,并加了MultiTrigger。

注意:俩个Condition,一个是从外面绑定过来的Tag,一个是ControlTemplate中Element的属性Tag。

因为有时候控件自带的Tag值不够使用,因此需要另一个Tag来支持Trigger里面的逻辑。

 

    <ControlTemplate TargetType="{x:Type p:InteractiveButton}">
        <Grid x:Name="RootGrid" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
            <Border Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                <ContentPresenter ContentSource="{TemplateBinding Content}" Margin="{TemplateBinding Padding}"
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
        <Image x:Name="Image5" Visibility="Collapsed" Source="{StaticResource Image.Titlebar.NewMessageNote}"/>
            </Border>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="Tag" Value="Searched">
                <Trigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Image5" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}" />
                            </ObjectAnimationUsingKeyFrames>
                            <DoubleAnimation Storyboard.TargetName="Image5" Storyboard.TargetProperty="Height"
                                             From="2" To="15" Duration="0:0:0.2"></DoubleAnimation>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Tag" Storyboard.TargetProperty="Tag">
                                <DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="NewMessageAnmation1" />
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
            </Trigger>
            <Trigger SourceName="RootGrid" Property="Tag" Value="NewMessageAnmation1">
                <Trigger.EnterActions>
                    <BeginStoryboard Name="BreatheStoryboard">
                        <Storyboard DesiredFrameRate="20">
                            <DoubleAnimation Storyboard.TargetName="Image5" Storyboard.TargetProperty="Height"
                                             From="10" To="2" RepeatBehavior="Forever" AutoReverse="True" Duration="0:0:0.68"></DoubleAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
            </Trigger>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="Tag" Value="Searching" />
                    <Condition SourceName="RootGrid" Property="Tag" Value="NewMessageAnmation1” />
                </MultiTrigger.Conditions>
                <Setter Property="Background" Value="#F4F4F4" />
            </MultiTrigger>

        </ControlTemplate.Triggers>
    </ControlTemplate>
    
    <Button Tag={Binding Type}/>

 

然后在另一窗口或者后台线程中,添加了PropertyChanged的属性Type,值改变时

        private string _type = string.Empty;
        public string Type
        {
            get { return _type; }
            set
            {
                _type = value;
                RaisePropertyChanged(nameof(Type));
            }
        }

 

引进上面的MultiTrigger中一个Condition 值变化,但是另一个Condition和Setter(Actions)引用了ControlTemplate中的Eelement,这时会引发

未将对象引用到实例

 

如上异常,解决方案:

用附加属性替代 SourceName="RootGrid" Property="Tag" .即可

    <ControlTemplate TargetType="{x:Type p:InteractiveButton}">
        <Grid x:Name="RootGrid" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
            <Border Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                <ContentPresenter ContentSource="{TemplateBinding Content}" Margin="{TemplateBinding Padding}"
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
        <Image x:Name="Image5" Visibility="Collapsed" Source="{StaticResource Image.Titlebar.NewMessageNote}"/>
            </Border>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="Tag" Value="Searched">
                <Trigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Image5" Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}" />
                            </ObjectAnimationUsingKeyFrames>
                            <DoubleAnimation Storyboard.TargetName="Image5" Storyboard.TargetProperty="Height"
                                             From="2" To="15" Duration="0:0:0.2"></DoubleAnimation>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(ui:TitlebarHelper.Type)">
                                <DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="NewMessageAnmation1" />
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
            </Trigger>
            <Trigger Property="ui:TitlebarHelper.Type" Value="NewMessageAnmation1">
                <Trigger.EnterActions>
                    <BeginStoryboard Name="BreatheStoryboard">
                        <Storyboard DesiredFrameRate="20">
                            <DoubleAnimation Storyboard.TargetName="Image5" Storyboard.TargetProperty="Height"
                                             From="10" To="2" RepeatBehavior="Forever" AutoReverse="True" Duration="0:0:0.68"></DoubleAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
            </Trigger>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="Tag" Value="Searching" />
                    <Condition Property="ui:TitlebarHelper.Type" Value="NewMessageAnmation1” />
                </MultiTrigger.Conditions>
                <Setter Property="Background" Value="#F4F4F4" />
            </MultiTrigger>

        </ControlTemplate.Triggers>
    </ControlTemplate>
    
    <Button Tag={Binding Type}/>

 

    public static class TitlebarTypeHelper
    {
        public static string GetType(DependencyObject obj)
        {
            return (string)obj.GetValue(TypeProperty);
        }

        public static void SetType(DependencyObject obj, string value)
        {
            obj.SetValue(TypeProperty, value);
        }

        /// <summary>
        /// 附加属性
        /// </summary>
        public static readonly DependencyProperty TypeProperty =
            DependencyProperty.RegisterAttached("Type", typeof(string), typeof(TitlebarTypeHelper),
                new PropertyMetadata(null));
    }

 

目录
相关文章
|
2月前
全局异常处理
全局异常处理
33 1
|
8月前
|
JSON Java API
优雅地进行全局异常处理、统一返回值封装、自定义异常错误码——Graceful-Response推荐
Graceful Response是一个Spring Boot体系下的优雅响应处理器,提供一站式统一返回值封装、全局异常处理、自定义异常错误码等功能,使用Graceful Response进行web接口开发不仅可以节省大量的时间,还可以提高代码质量,使代码逻辑更清晰。
276 0
|
12月前
|
运维 Prometheus 监控
java异常 | 处理规范、全局异常、Error处理
java异常 | 处理规范、全局异常、Error处理
|
2月前
|
前端开发
Nestjs(五)异常处理方式(异常过滤器)
Nestjs(五)异常处理方式(异常过滤器)
78 0
|
11月前
全局参数、异常处理
全局参数、异常处理
114 0
|
12月前
|
Java
定义全局异常和全局异常处理器
定义全局异常和全局异常处理器
|
Java Spring
任何 bean 初始化回调前自定义逻辑
任何 bean 初始化回调前自定义逻辑
|
C++
解析一下C++的异常处理
解析一下C++的异常处理
105 0
解析一下C++的异常处理
|
Java 开发者
全局异常处理器|学习笔记
快速学习全局异常处理器
168 0
全局异常处理器|学习笔记