Как рассчитать положение элемента управления на экране (в пикселях) в WinUI 3C#

Место общения программистов C#
Ответить
Anonymous
 Как рассчитать положение элемента управления на экране (в пикселях) в WinUI 3

Сообщение Anonymous »

Моя цель — вычислить положение левого края среднего блока на экране. Это используется для позиционирования плавающего окна точно вдоль левого края.
Проблема в том, что значение, которое я получаю при вычислении положения экрана, не соответствует ожидаемому. Это тестовое приложение показывает расчетное положение «От экрана» и фактическое положение плавающих окон на экране при перетаскивании на место.

Изображение
Расчеты координат в приложении Windows
Под «ControlBlock» указана ширина ControlBlock а «Позиция окна» — это координаты экрана, рассчитанные с помощью:

Код: Выделить всё

//Application window position
var mainWindow = (Application.Current as App) ? ._window;
PointInt32 windowPos = mainWindow.AppWindow.Position;

//Get monitor from a window
IntPtr hwnd = WinRT.Interop.WindowNative.GetWindowHandle(mainWindow);
IntPtr hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

//Control block
WindowPos.Text = $ "Window Pos: ({windowPos.X:N0}, {windowPos.Y:N0})";
ControlBlockWidth.Text = $ "Width: {ControlBlock.ActualWidth:N0}";
Ниже «LeftBlock» указана ширина LeftBlock, а «LeftBlock Screen» — неправильно рассчитанное положение левого края LeftBlock на экране:

Код: Выделить всё

//Left block
LeftBlockWidth.Text = $ "Width: {LeftBlock.ActualWidth:N0}";

var transformLeftBlock = LeftBlock.TransformToVisual(mainWindow.Content as UIElement);
var pointLeftBlock = transformLeftBlock.TransformPoint(new Point(0, 0));

LeftBlockScreenCoord.Text = $ "LeftBlock Screen: ({pointLeftBlock.X + windowPos.X:N0}, {pointLeftBlock.Y + windowPos.Y:N0})";
Ниже MiddleBlock рассчитываются различные значения: (Наиболее интересным является «С экрана», его значение X должно быть таким же, как показано в «Позиции экрана» плавающего окна).

Код: Выделить всё

//Middle block
var transform = MiddleBlock.TransformToVisual(LeftBlock);
var pointInRoot = transform.TransformPoint(new Point(0, 0));
MiddleBlockFromLeftBlock.Text = $ "From LeftBlock: ({pointInRoot.X:N0}, {pointInRoot.Y:N0})";

var transform2 = MiddleBlock.TransformToVisual(RootGrid);
var pointInRoot2 = transform2.TransformPoint(new Point(0, 0));
MiddleBlockFromRootGrid.Text = $ "From RootGrid: ({pointInRoot2.X:N0}, {pointInRoot2.Y:N0})";

var transform3 = MiddleBlock.TransformToVisual(mainWindow.Content as UIElement);
var pointInRoot3 = transform3.TransformPoint(new Point(0, 0));
MiddleBlockWindowCoord.Text = $ "From AppWindow: ({pointInRoot3.X:N0}, {pointInRoot3.Y:N0})";

MiddleBlockScreenCoord.Text = $ "From Screen: ({pointInRoot3.X + windowPos.X:N0}, {pointInRoot3.Y + windowPos.Y:N0})";
Плавающие окна позиционируются по координатам экрана
Плавающие окна перетаскиваются в нужное положение, а «Положение экрана» — это значение «floatingWindow.AppWindow.Position».
Я также могу указать точные координаты экрана, которые затем позиционируют плавающее окно с помощью «floatingWindow.AppWindow.Move(new) PointInt32(targetX, targetY))»
Если я расположим плавающее окно ближе к правой стороне экрана, координата X будет равна 3397 + ширина окна (500), что близко к разрешению экрана (3840x2160).
Коэффициент масштабирования между виртуальным разрешением и реальным разрешением
Я попытался получить коэффициент масштабирования, который обсуждался в этом вопросе, но это 1.0.
Как определить текущее разрешение экрана?
Вопрос
Кто-нибудь знает, как правильно рассчитать положение левого края экрана MiddleBlock? Очевидно, что координаты внутри приложения не являются пикселями. Нужно ли какое-либо преобразование для перехода от координат приложения к координатам экрана?

Подробнее здесь: https://stackoverflow.com/questions/798 ... in-winui-3
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»