You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi问题:鼠标悬停子控件时父控件失焦致阴影效果消失

解决Panel悬停子控件时阴影消失的问题

问题根源

你遇到的问题本质是WPF控件的鼠标命中测试逻辑:

  • 默认情况下,Panel的Background为null,不会参与鼠标命中测试。当鼠标移到子控件Button上时,父Panel的IsMouseOver会直接变为false,导致阴影触发条件失效。
  • 改用IsFocused也不行,因为WPF中焦点只能属于单个控件,子控件获得焦点后父控件必然失去焦点。

可行解决方案

方案1:给父Panel设置透明背景(最简单)

只要给父Panel添加Background="Transparent",就能让它参与鼠标命中测试。此时即使鼠标悬停在子控件上,父控件的IsMouseOver依然会保持true,阴影效果就能持续显示。

示例XAML代码:

<Panel Background="Transparent">
    <Panel.Style>
        <Style TargetType="Panel">
            <Setter Property="Effect">
                <Setter.Value>
                    <DropShadowEffect BlurRadius="0" Opacity="0"/>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Effect">
                        <Setter.Value>
                            <DropShadowEffect BlurRadius="10" Opacity="0.5" Color="Gray"/>
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Panel.Style>
    <Button Content="点击按钮"/>
</Panel>

方案2:用MultiDataTrigger监听父/子控件的鼠标状态

如果不能设置透明背景(比如和现有样式冲突),可以用MultiDataTrigger同时监听父控件和子控件的IsMouseOver状态,只要其中一个为true就激活阴影。

示例XAML代码:

<Panel>
    <Panel.Style>
        <Style TargetType="Panel">
            <Setter Property="Effect">
                <Setter.Value>
                    <DropShadowEffect BlurRadius="0" Opacity="0"/>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <!-- 父控件自身悬停时激活阴影 -->
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Effect">
                        <Setter.Value>
                            <DropShadowEffect BlurRadius="10" Opacity="0.5" Color="Gray"/>
                        </Setter.Value>
                    </Setter>
                </Trigger>
                <!-- 子控件悬停时也激活阴影 -->
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding IsMouseOver, ElementName=ChildBtn}" Value="True"/>
                    </MultiDataTrigger.Conditions>
                    <Setter Property="Effect">
                        <Setter.Value>
                            <DropShadowEffect BlurRadius="10" Opacity="0.5" Color="Gray"/>
                        </Setter.Value>
                    </Setter>
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Panel.Style>
    <Button x:Name="ChildBtn" Content="点击按钮"/>
</Panel>

方案3:后台代码手动控制阴影状态

如果XAML触发器的方式不满足需求,也可以通过后台事件处理来手动控制阴影:

  • 父Panel和子Button的MouseEnter事件触发时,直接激活阴影
  • 离开事件触发时,先判断鼠标是否还在父Panel的范围内,只有完全离开时才关闭阴影

示例C#代码:

private void ParentPanel_MouseEnter(object sender, MouseEventArgs e)
{
    var panel = sender as Panel;
    panel.Effect = new DropShadowEffect { BlurRadius = 10, Opacity = 0.5, Color = Colors.Gray };
}

private void ParentPanel_MouseLeave(object sender, MouseEventArgs e)
{
    var panel = sender as Panel;
    var hitTest = VisualTreeHelper.HitTest(panel, e.GetPosition(panel));
    // 只有鼠标完全离开父Panel范围时才关闭阴影
    if (hitTest == null || !panel.IsAncestorOf(hitTest.VisualHit))
    {
        panel.Effect = new DropShadowEffect { BlurRadius = 0, Opacity = 0 };
    }
}

// 子按钮的事件直接复用父Panel的处理逻辑
private void ChildBtn_MouseEnter(object sender, MouseEventArgs e)
{
    ParentPanel_MouseEnter(ParentPanel, e);
}

private void ChildBtn_MouseLeave(object sender, MouseEventArgs e)
{
    ParentPanel_MouseLeave(ParentPanel, e);
}

内容的提问来源于stack exchange,提问作者Zakaria Mimeche

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 06:25:11