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));
    }
时间: 2024-09-28 22:05:55

MultiTigger 绑定异常处理的相关文章

spring boot 全局异常处理

import cn.sisyphe.framework.web.exception.DataException; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.converter.HttpMessageConversionException; import org.springframework.validation.Bin

WebApi学习系列

  最近有一些时间,打算学习和整理一下Web API的一些学习资料的翻译工作.以下是对Web API 的大概目录的整理.欢迎更多的朋友一起加入到学习Web API 的队伍中来,如果你想贡献自己的,请联系QQ:546975675 目录 入门 路由 Web API如何与数据库交互 移动客户端访问Web API 在Web API中实现OData 序列化和模型绑定 异常处理 测试和调试 Web API之安全授权 如何托管 Web API Web API 高级主题 Web API 版本 附加资源 API参

Android 捕获系统全局异常

Android系统的"程序异常退出",给应用的用户体验造成不良影响.为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理.通过Thread.setDefaultUncaughtExceptionHandler()方法将异常处理类设置到线程上即可. 1.异常处理类,代码如下: [java] view plaincopy public class CrashHandler implements UncaughtExceptionHandle

Laravel源码解析--看看Lumen到底比Laravel轻在哪里

在前面一篇<Laravel源码解析--Laravel生命周期详解>中我们利用xdebug详细了解了下Laravel一次请求中到底做了哪些处理.今天我们跟 Lumen 对比下,看看 Lumen 比 Laravel 轻在哪里? 1.Lumen生命周期 相比于Laravel,在Lumen中,你对框架有着更多的控制权.Lumen的入口文件相比于Laravel要简单许多. <?php /* |-----------------------------------------------------

面向对象,绑定方法与异常处理(七)

1.1 继承与派生 1.1.1 什么是继承     是一种新建类的方式,新建的类称为子类,子类会遗传父类的属性,可以减少代码冗余     在python中,子类(派生类)可以继承一个或者多个父类(基类,超类)   python中类的继承分为:单继承和多继承 class Parent1: #定义父类 pass class Parent2(object): #定义父类 pass class Sub1(Parent1): ##单继承,基类是Parent1,派生类是Sub1 pass class Sub

快速入门系列--WCF--04元数据和异常处理

本章节将进行元数据和异常处理的介绍,这部分内容概念型比较强,可以快速浏览一下就好. 客户端和服务器借助于终结点进行通信,服务的提供者通过一个或者多个终结点将服务发布出来,服务的消费者则通过创建与之匹配的终结点进行服务的调用.可以将服务的元数据看做是它所有终结点的描述,它以一种易于交换的数据格式(WSDL, XSD, WS-POLICY)描述该服务的所有终结点信息.WCF提供了一个完整的元数据架构体系,易于元数据的导出.发布.获取和导入. 服务的元数据实际上是对其所具有的终结点的描述,终结点由地址

Android 异常处理最佳实践

一个好的app 异常处理机制 我认为应该至少包含以下几个功能: 1.能把错误信息上传到服务器  让开发者可以持续改进app 2.错误信息至少应该包含 是否在主进程 是否在主线程 等可以帮助程序员定位的信息 3.最好包含手机硬件及软件信息. 4.主进程引发的异常 最好交由系统自己处理 也就是让用户可以感知到 那种(当然你也可以自己定义一套更有意思的感知系统对话框等,具体可参考各种有意思的404界面) 5.子进程引发的异常最好别让用户感知到.比如push之类的 这种 和用户感知弱关联的这种.最好发生

Java web的几种异常处理 (转)

一.在servlet容器中处理异常 以下两种方式: 1. 在web.xml定义异常处理  如果没有在web的应用中作异常处理,那么异常就会抛给Servlet容器,应该说此时Servlet容器是处理异常的时机了.如果此时Servlet容器还不对异常处理的话,那么容器会把异常的内容直接显示给访问者.  Servlet容器通过web.xml配置对异常的处理.在web.xml中进行异常处理的配置是通过<error-page>元素来表示,支持两种类型的异常拦截. 1)依据http请求所返回的状态码来拦截

Python之异常处理、模块与包

MarkdownPad Document 错误与异常处理 程序中错误分成两种 语法错误:过不了Python解释器 逻辑错误 异常处理 什么是异常处理 Python解释器检测到错误,触发异常,在发生异常时捕捉异常,如果捕捉成功则进入另外一个处理分支,是程序不会崩溃,这就是异常处理 异常处理机制就是来增强程序的健壮性与容错性 常用异常 AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x IOError 输入/输出异常:基本上是无法打开文件 ImportEr