sto*_*one 21 wpf adorner mouseevent transparent-control
我真正想要的是一个IsHitTestVisible版本,它忽略鼠标点击事件但仍然捕获鼠标进入和离开事件.
背景:无论何时,都会在控件下弹出信息覆盖.这是一个要求,所以我不能自由地删除这种行为.这是使用包含矩形形状的装饰器实现的,该装饰器填充有图像画笔.所有控件都以编程方式创建,不涉及XAML.
期望的行为:当用户将鼠标悬停在Rectangle上时,它应该变为部分透明.这样他们就可以看到叠加层下方的其他控件并单击它们.当用户点击叠加层时,点击应该传递到叠加层下面的任何控件,即用户点击的位置.
问题:如果我将IsHitTestVisible设置为True以允许鼠标点击通过,我不会获得MouseEnter事件.
是否有一种简单的方法可以让IsHitTestVisible保持True,然后将2-3个事件传递给adorner下面的正确控件?我正在寻找一个不涉及计算光标下方控件的解决方案,因为WPF显然能够为我做这个.
或者,我可以将IsHitTestVisible设置为False,然后使用另一种简单方法来确定鼠标何时在装饰器上方?
更新:我仍然希望得到答案,但截至目前,最有希望的解决方案似乎是保持IsHitTestVisible为真,并使用WPF命中测试API来确定鼠标光标下面的控件类型; 如果它是我所知道的,我会向它发送一个Click命令.不过,不确定这是否值得做; 截至目前,点击解除我的叠加层,因此用户只需点击两次.
谢谢!
由于IsHitTestVisible ="False"禁用所有鼠标交互,因此它似乎不是任何干净的方式.我试过了
看起来真正实现这一点的唯一方法是在OnMouseDown中设置IsHitTestVisible ="False",然后使用SendInput模拟新的MouseClick.不是很漂亮,但它完成了工作.
protected override void OnMouseDown(MouseButtonEventArgs e)
{
IsHitTestVisible = false;
Action action = () =>
{
MouseSimulator.ClickLeftMouseButton();
IsHitTestVisible = true;
};
this.Dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
}
public class MouseSimulator
{
[DllImport("user32.dll", SetLastError = true)]
static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);
[StructLayout(LayoutKind.Sequential)]
struct INPUT
{
public SendInputEventType type;
public MouseKeybdhardwareInputUnion mkhi;
}
[StructLayout(LayoutKind.Explicit)]
struct MouseKeybdhardwareInputUnion
{
[FieldOffset(0)]
public MouseInputData mi;
[FieldOffset(0)]
public KEYBDINPUT ki;
[FieldOffset(0)]
public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}
struct MouseInputData
{
public int dx;
public int dy;
public uint mouseData;
public MouseEventFlags dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[Flags]
enum MouseEventFlags : uint
{
MOUSEEVENTF_MOVE = 0x0001,
MOUSEEVENTF_LEFTDOWN = 0x0002,
MOUSEEVENTF_LEFTUP = 0x0004,
MOUSEEVENTF_RIGHTDOWN = 0x0008,
MOUSEEVENTF_RIGHTUP = 0x0010,
MOUSEEVENTF_MIDDLEDOWN = 0x0020,
MOUSEEVENTF_MIDDLEUP = 0x0040,
MOUSEEVENTF_XDOWN = 0x0080,
MOUSEEVENTF_XUP = 0x0100,
MOUSEEVENTF_WHEEL = 0x0800,
MOUSEEVENTF_VIRTUALDESK = 0x4000,
MOUSEEVENTF_ABSOLUTE = 0x8000
}
enum SendInputEventType : int
{
InputMouse,
InputKeyboard,
InputHardware
}
public static void ClickLeftMouseButton()
{
INPUT mouseDownInput = new INPUT();
mouseDownInput.type = SendInputEventType.InputMouse;
mouseDownInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTDOWN;
SendInput(1, ref mouseDownInput, Marshal.SizeOf(new INPUT()));
INPUT mouseUpInput = new INPUT();
mouseUpInput.type = SendInputEventType.InputMouse;
mouseUpInput.mkhi.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_LEFTUP;
SendInput(1, ref mouseUpInput, Marshal.SizeOf(new INPUT()));
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7256 次 |
| 最近记录: |