触发器(三、条件触发)

在使用触发器的过程中,我们经常发现真正关注的只有一部分数据,并不需要对每个操作都进行触发或处理。

此时可以用到条件触发,条件触发是有限制的,根据不同的需求,可以分为以下几个应用场景:

1.只关注某几列的数据变更,用update of

只有在update后面才能跟of,在insert和delete中无法只关注某几列,

会报错ORA-04073: column list not valid for this trigger type

比如下面的触发器,只关心2个字段的变更


分别执行2个update语句


of后面的字段更新触发了,而没有关注的字段更新没有触发。


2.只关心特定条件的记录,用WHEN

在有些设计不佳的应用中,有些字段可能经常会被update成原值,即无效的update,对这些update根本没有必要关注。

此时可以用when做条件过滤,WHEN条件在几乎所有触发器中都可以使用,并不局限于在update触发器。

下面用一个简单的案例看一下when的用法,判断OBJECT_NAME字段被修改成不一样的值时才执行触发


注意:WHEN条件里的OLD和NEW是不能带冒号:的

否则会报错ORA-25000: invalid use of bind variable in trigger WHEN clause


<think> 我们之前讨论的是WPF按钮样式,其中包含一个触发器(当IsMouseOver为True时改变边框颜色)。现在用户反馈“上述触发器不能触发”,我们需要分析可能的原因并提供解决方案。 可能的原因: 1. 样式未正确应用:按钮没有使用这个样式。 2. 边框属性覆盖:可能在别处设置了边框颜色,导致触发器设置的边框颜色被覆盖。 3. 触发器条件不满足:可能是鼠标事件没有被正确触发(例如,按钮被其他元素覆盖,或者IsHitTestVisible为false)。 4. 边框名称错误:在Trigger的TargetName中指定的名称与Border的x:Name不一致。 5. 模板绑定问题:在ControlTemplate中,Border的BorderBrush可能被模板绑定覆盖,而触发器设置的只是本地值,可能无法覆盖模板绑定。 检查点: - 确保按钮应用了样式:Button的Style属性是否设置为`{StaticResource DhButtonStyle1}`。 - 检查Border的x:Name是否确实是"border"(注意大小写)。 - 检查Border的BorderThickness是否大于0?如果BorderThickness为0,即使改变BorderBrush也看不到效果。 - 检查是否在别处(如样式、触发器等)设置了更高的优先级值覆盖了触发器的设置。 解决方案步骤: 1. 确保BorderThickness已设置: 在Border元素上,设置BorderThickness为一个可见的值(如1)。原代码中未设置BorderThickness,默认为0,所以即使改变了BorderBrush也看不到。 2. 确保模板绑定不会覆盖触发器的设置: 在原始代码中,Border的BorderBrush是直接设置为Transparent的,而触发器尝试改变它。这应该是可行的,因为触发器的设置会覆盖本地值。但是,如果BorderBrush使用了TemplateBinding,则可能不同。原代码中并没有使用TemplateBinding,所以没问题。但为了确保,我们可以这样写: ```xml <Border x:Name="border" CornerRadius="5" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1"> ``` 这样,触发器中设置的BorderBrush会覆盖模板绑定(因为触发器设置的是本地值,优先级高于模板绑定)。 3. 检查触发器是否正确定义。 修改后的样式代码(修正触发器不能触发的问题): 主要改动: - 添加了BorderThickness="1"(必须,否则边框看不见) - 确保BorderBrush的初始值不是透明(但这里触发器会改变它,所以初始透明也没关系,但初始时边框不可见,悬停时出现) 修改后的样式代码: ```xml <Style x:Key="DhButtonStyle1" TargetType="Button"> <Setter Property="Background" Value="Transparent"/> <Setter Property="BorderBrush" Value="Transparent"/> <Setter Property="Margin" Value="10,10,10,0"/> <Setter Property="Height" Value="50"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <!-- 设置BorderThickness为1,这样边框才会显示 --> <Border x:Name="border" CornerRadius="5" BorderBrush="Transparent" BorderThickness="1"> <StackPanel Orientation="Horizontal"> <Image Source="/Resource/Image/3.png" Height="30"/> <TextBlock Text="特种设备" FontFamily="Arial" FontSize="15" Foreground="#FFD8D6D6" VerticalAlignment="Center" Margin="5,0,0,0"/> </StackPanel> </Border> <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <!-- 设置边框颜色为LightGray,注意此时BorderThickness已为1,所以会显示 --> <Setter TargetName="border" Property="BorderBrush" Value="LightGray"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> ``` 测试步骤: 1. 将上述样式放入资源字典(如Window.Resources或App.xaml)。 2. 在按钮上应用该样式:`<Button Style="{StaticResource DhButtonStyle1}"/>` 3. 运行程序,将鼠标移到按钮上,观察边框是否变为浅灰色。 如果仍然不触发,请检查: - 是否在别处定义了更高优先级的样式覆盖了这个触发器- 按钮是否被其他元素遮挡(例如,一个透明的元素覆盖在按钮上方,导致按钮无法接收到鼠标事件)? - 按钮的IsHitTestVisible是否为true?IsEnabled是否为true? 如果上述方案无效,可以尝试添加一个背景色(即使是透明的),确保边框区域可以正确接收鼠标事件。 另外,考虑添加一个IsPressed触发器以验证触发器的整体功能是否正常: ```xml <Trigger Property="IsPressed" Value="True"> <Setter TargetName="border" Property="BorderBrush" Value="DarkGray"/> </Trigger> ``` 这样按下按钮时边框会变为深灰色,用于测试触发器是否工作。 最后,如果问题仍然存在,请使用Snoop或Live Visual Tree等工具检查运行时可视化树,查看Border的实际属性值。 相关问题: </think> 针对触发器无法触发的问题,我将提供详细的分析和解决方案。以下是常见原因和修复方法: ### 常见原因及解决方案 1. **BorderThickness 未设置** 如果边框厚度为0,即使设置了边框颜色也不会显示 ```xml <!-- 修正前 --> <Border BorderBrush="Transparent"> <!-- 修正后 --> <Border BorderBrush="Transparent" BorderThickness="1"> ``` 2. **样式未正确应用** 确保按钮正确引用了样式资源 ```xml <!-- 错误用法 --> <Button> <!-- 正确用法 --> <Button Style="{StaticResource DhButtonStyle1}"> ``` 3. **层级优先级问题** 添加明确的层级优先级声明 ```xml <ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="True"> <!-- 添加明确的优先级声明 --> <Setter Property="Border.BorderBrush" TargetName="border" Value="LightGray"> <Setter.Value> <SolidColorBrush Color="LightGray"/> </Setter.Value> </Setter> </Trigger> </ControlTemplate.Triggers> ``` 4. **缺少状态转换动画** 添加状态转换动画确保平滑过渡 ```xml <ControlTemplate.Resources> <Storyboard x:Key="MouseOverAnimation"> <ColorAnimation Duration="0:0:0.2" Storyboard.TargetName="border" Storyboard.TargetProperty="BorderBrush.Color" To="LightGray"/> </Storyboard> </ControlTemplate.Resources> <ControlTemplate.Triggers> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <BeginStoryboard Storyboard="{StaticResource MouseOverAnimation}"/> </EventTrigger> </ControlTemplate.Triggers> ``` ### 完整修复后的代码 ```xml <Style x:Key="DhButtonStyle1" TargetType="Button"> <Setter Property="Background" Value="Transparent"/> <Setter Property="BorderBrush" Value="Transparent"/> <Setter Property="Margin" Value="10,10,10,0"/> <Setter Property="Height" Value="50"/> <Setter Property="Cursor" Value="Hand"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <!-- 修复1:添加BorderThickness --> <Border x:Name="border" CornerRadius="5" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1"> <StackPanel Orientation="Horizontal"> <Image Source="/Resource/Image/3.png" Height="30"/> <TextBlock Text="特种设备" FontFamily="Arial" FontSize="15" Foreground="#FFD8D6D6" VerticalAlignment="Center" Margin="5,0,0,0"/> </StackPanel> </Border> <ControlTemplate.Resources> <!-- 可选:添加平滑过渡动画 --> <Storyboard x:Key="HoverAnimation"> <ColorAnimationUsingKeyFrames Storyboard.TargetName="border" Storyboard.TargetProperty="BorderBrush.Color"> <LinearColorKeyFrame KeyTime="0:0:0.1" Value="LightGray"/> </ColorAnimationUsingKeyFrames> </Storyboard> </ControlTemplate.Resources> <ControlTemplate.Triggers> <!-- 修复3:添加明确的Setter声明 --> <Trigger Property="IsMouseOver" Value="True"> <Setter TargetName="border" Property="BorderBrush" Value="LightGray"/> <!-- 可选:触发动画 --> <Trigger.EnterActions> <BeginStoryboard Storyboard="{StaticResource HoverAnimation}"/> </Trigger.EnterActions> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> ``` ### 调试技巧 1. **使用Snoop工具** 使用 [WPF Snoop](https://github.com/snoopwpf/snoopwpf) 实时检查依赖属性值 2. **添加调试边框** 临时添加调试边框确认布局: ```xml <Border BorderBrush="Red" BorderThickness="1"> <!-- 原始内容 --> </Border> ``` 3. **检查事件路由** 添加事件监听器确认鼠标事件是否触发: ```csharp button.MouseEnter += (s, e) => Debug.WriteLine("Mouse entered"); button.MouseLeave += (s, e) => Debug.WriteLine("Mouse left"); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值