Отключить фокус мыши над детьми холста - PullRequest
0 голосов
/ 04 июня 2019

Я создаю полноэкранное прозрачное окно, чтобы показать перекрестие на некоторых взаимодействиях в плагине Revit. Но когда линии создаются на холсте и пересекаются в позиции мыши - курсор мыши фокусируется на линиях. Но курсор должен быть сфокусирован на окне Revit

Я пытаюсь использовать свойства (для окна, для холста и для линий): IsHitTestVisible="False" IsEnable="False" IsManipulationEnabled="False" FocusVisualStyle="{x:Null}"

Xaml:

<Window
    x:Class="mprPatterns.Views.PickCrosshairWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    AllowsTransparency="True" SnapsToDevicePixels="True"
    WindowStyle="None" Background="Transparent"
    ShowActivated="True" ShowInTaskbar="False"
    Topmost="True" IsHitTestVisible="False">
    <Canvas x:Name="Canvas"/>
</Window>

CodeBehind:

namespace mprPatterns.Views
{
    using System.Diagnostics;
    using System.Windows;
    using System.Windows.Forms;
    using System.Windows.Media;
    using System.Windows.Shapes;
    using Gma.System.MouseKeyHook;

    public partial class PickCrosshairWindow
    {
        private IKeyboardMouseEvents _keyboardMouseEvents;

        public PickCrosshairWindow()
        {
            InitializeComponent();
            if (Screen.AllScreens.Length > 1)
            {
                var totalSize = ScreenTotalSize();

                Width = totalSize.Width;
                Height = totalSize.Height;
                Left = 0;
                Top = 0;
            }
            else
            {
                WindowState = WindowState.Maximized;
            }
            Closing += (sender, args) => { StopShowCrosshair(); };
        }

        public void StartShowCrosshair()
        {
            SubscribeGlobal();
        }

        public void StopShowCrosshair()
        {
            ClearCanvas();
            Unsubscribe();
        }

        public void ClearCanvas()
        {
            Canvas.Children.Clear();
        }

        private void SubscribeGlobal()
        {
            Unsubscribe();
            Subscribe(Hook.GlobalEvents());
        }

        private void Subscribe(IKeyboardMouseEvents events)
        {
            _keyboardMouseEvents = events;

            _keyboardMouseEvents.MouseMove += HookManager_MouseMove;
        }

        private void Unsubscribe()
        {
            if (_keyboardMouseEvents == null) return;

            _keyboardMouseEvents.MouseMove -= HookManager_MouseMove;

            _keyboardMouseEvents.Dispose();
            _keyboardMouseEvents = null;
        }


        private void HookManager_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            Debug.Print($"x={e.X:0000}; y={e.Y:0000}");
            Debug.Print(Screen.PrimaryScreen.Bounds.Width.ToString());
            var screenTotalSize = ScreenTotalSize();
            Canvas.Children.Clear();
            Line line = new Line();
            line.Stroke = System.Windows.Media.Brushes.Red;
            line.StrokeDashArray = new DoubleCollection { 10, 5 };
            line.X1 = 0;
            line.Y1 = e.Y;
            line.X2 = screenTotalSize.Width;
            line.Y2 = e.Y;

            Line line2 = new Line();
            line2.Stroke = System.Windows.Media.Brushes.Red;
            line2.StrokeDashArray = new DoubleCollection { 10, 5 };
            line2.X1 = e.X;
            line2.Y1 = 0;
            line2.X2 = e.X;
            line2.Y2 = screenTotalSize.Height;

            Canvas.Children.Add(line);
            Canvas.Children.Add(line2);
        }

        private static System.Drawing.Rectangle ScreenTotalSize()
        {
            System.Drawing.Rectangle totalSize = System.Drawing.Rectangle.Empty;
            foreach (Screen s in Screen.AllScreens)
                totalSize = System.Drawing.Rectangle.Union(totalSize, s.Bounds);
            return totalSize;
        }
    }
}

Реализация:

_parentWindow.Hide();

try
{
    PickCrosshairWindow.StartShowCrosshair();
    ObjectSnapTypes snapTypes = ObjectSnapTypes.Endpoints | ObjectSnapTypes.Intersections;
    XYZ point = RevitInterop.UiDocument.Selection.PickPoint(snapTypes, "Select an end point or intersection");
    PickCrosshairWindow.ClearCanvas();

    PickCrosshairWindow.StartShowCrosshair();
    point = RevitInterop.UiDocument.Selection.PickPoint(snapTypes, "Select an end point or intersection");
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException)
{
    // todo ignore?
}
catch (Exception exception)
{
    ExceptionBox.Show(exception);
}
finally
{
    PickCrosshairWindow.StopShowCrosshair();
    _parentWindow.Show();
}

Единственное, что помогает, это сдвигать строки с позиции курсора:

Line line = new Line();
line.Stroke = System.Windows.Media.Brushes.Red;
line.StrokeDashArray = new DoubleCollection { 10, 5 };
line.X1 = 0;
line.Y1 = e.Y + 5;
line.X2 = screenTotalSize.Width;
line.Y2 = e.Y + 5;

Line line2 = new Line();
line2.Stroke = System.Windows.Media.Brushes.Red;
line2.StrokeDashArray = new DoubleCollection { 10, 5 };
line2.X1 = e.X + 5;
line2.Y1 = 0;
line2.X2 = e.X + 5;
line2.Y2 = screenTotalSize.Height;

Но это не решение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...