XAML 如何使用可单击控件创建半透明覆盖

nbewdwxp  于 2023-11-14  发布在  其他
关注(0)|答案(1)|浏览(118)

我想创建一个半透明的窗口(黑色,不透明)和一些控件(可能是一个+和-来增加/减少不透明)。
How can I make an "overlay" window that allows mouse clicks to pass through to windows below it, but still allow some controls to be clicked?
只有当窗口完全透明时,这才能在预期的时间内工作,添加一些不透明度会破坏叠加行为
如何在WPF中创建允许鼠标事件通过的半透明窗口
使用这种方法,我失去了控件的单击功能。
我如何合并这两个?我可以改变到其他框架,如winforms,winui,如果这将使事情更容易

ljsrvy3e

ljsrvy3e1#

根据WS_EX_TRANSPARENT explanation
WS_EX_TRANSPARENT使你的事件(如鼠标点击)通过你的窗口,以及其他的事情。不透明度是一个单独的概念,它指示窗口管理器在绘制表单时应用字母借贷。
所以,如果我理解你的问题是正确的,你想有一个Transparent Window,允许点击它下面的对象,但也有该窗口上的控件,也可以点击。
为了做到这一点,你需要找到一个妥协。
因为当你应用WS_EX_TRANSPARENT时,它就不再是可点击的了,所以为了 * 回到 * 正常的Window,你需要以某种方式触发一个方法来重置WS_EX_TRANSPARENT
我已经在.NET6和WPF中创建了一个示例,其中我在PreviewKeyDown事件上切换WS_EX_TRANSPARENT。当然,当尝试在此示例上重置WS_EX_TRANSPARENT时,必须关注Window。

XAML

<Window x:Class="WpfApp8.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:WpfApp8"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Title="MainWindow"
        Width="300"
        Height="300"
        WindowStyle="None"
        AllowsTransparency="True"
        Topmost="True"
        BorderThickness="5"
        BorderBrush="LimeGreen"
        Background="Transparent"
        PreviewKeyDown="Window_PreviewKeyDown"
        mc:Ignorable="d">

    <DockPanel>
        <Border Height="40"
                DockPanel.Dock="Top"
                Background="Blue"
                MouseDown="Border_MouseDown"/>

        <Button x:Name="button"
                Grid.Row="2"
                Width="75"
                Height="50"
                Margin="10"
                DockPanel.Dock="Bottom"
                Content="Button"
                Click="button_Click"/>

        <Border Background="Black" Opacity="0.5"/>
    </DockPanel>
</Window>

字符串

代码背后

namespace WpfApp8
{
    public partial class MainWindow : Window
    {
        private bool _borderClicked;

        private IntPtr _handle;

        public MainWindow()
        {
            InitializeComponent();
        }

        protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);
            _handle = new WindowInteropHelper(this).Handle;
            WindowsServices.SetWindowExNormal(_handle);
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            this.BorderBrush = !_borderClicked ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.LimeGreen);
            _borderClicked = !_borderClicked;
        }

        private void Window_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == Key.D1 && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
            {
                WindowsServices.SetWindowExNormal(_handle);
            }
            else if (e.Key == Key.D2 && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
            {
                WindowsServices.SetWindowExTransparent(_handle);
            }
        }

        private void Border_MouseDown(object sender, MouseButtonEventArgs e)
        {
            // Drag window
            this.DragMove();
        }
    }

    public static class WindowsServices
    {
        const int WS_EX_TRANSPARENT = 0x00000020;
        const int GWL_EXSTYLE = (-20);

        [DllImport("user32.dll")]
        static extern int GetWindowLong(IntPtr hwnd, int index);

        [DllImport("user32.dll")]
        static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);

        public static void SetWindowExTransparent(IntPtr hwnd)
        {
            var extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
            SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_TRANSPARENT);
        }

        public static void SetWindowExNormal(IntPtr hwnd)
        {
            int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
            SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle & ~WS_EX_TRANSPARENT);
        }
    }
}


的数据

相关问题