Вызов методов элемента управления представлением для доступа к их результату в ViewModel — подход, совместимый с MVVMC#

Место общения программистов C#
Ответить
Anonymous
 Вызов методов элемента управления представлением для доступа к их результату в ViewModel — подход, совместимый с MVVM

Сообщение Anonymous »

Как и в названии; есть ли какой-нибудь «правильный» способ сделать это? Является ли необходимость сделать это ошибкой дизайна?
Контекст:
Я создаю инструмент для аннотаций изображений. Я хочу зарегистрировать нажатия указателя, которые создают ограничивающие рамки на данном изображении, и отображать рамки по мере их создания. До сих пор я полагался на собственный блок изображения из этого репозитория:
https://github.com/sn4k3/UVtools/tree/m ... iaControls
Этот элемент управления AdvancedImageBox содержит метод, который возвращает координаты пикселей изображения при нажатии указателя, и это то, что мне нужно. Он также позволяет панорамировать и масштабировать, а также предоставляет пиксельную сетку при большом увеличении. Вышеупомянутый метод не привязан к какому-либо конкретному свойству. До сих пор я использовал собственное поведение для доступа к этому методу (и позиции указателя, которая на самом деле является представленной как свойство, но я решил, что с таким же успехом можно вернуть обе позиции вместе):

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

using System;
using System.Windows.Input;
using Avalonia.Xaml.Interactivity;
using Avalonia;
using UVtools.AvaloniaControls;

namespace ImageAnnotationTool.Behaviors;

public class InvokeImageCoordinateAction : AvaloniaObject, IAction
{
public static readonly StyledProperty CommandProperty =
AvaloniaProperty.Register(
nameof(Command));

public ICommand? Command
{
get => GetValue(CommandProperty);
set => SetValue(CommandProperty, value);
}

public object? Execute(object? sender, object? parameter)
{
if (sender is not AdvancedImageBox imgBox || Command is null)
{
return null;
}

Point pointer = imgBox.PointerPosition;
Point pixel = imgBox.PointToImage(pointer);

var outputTuple = new Tuple(pointer, pixel);

if (Command.CanExecute(outputTuple))
Command.Execute(outputTuple);

return outputTuple;
}
}
Я думаю, этот подход не нарушает MVVM. Однако он выдает подавленные исключения из-за доступа к потоку, отличному от пользовательского интерфейса (System.InvalidOperationException: вызов из недопустимого потока). Я полагаю, что это не следует игнорировать.
Еще одна проблема, которую я обнаружил при этом подходе, — это сложность управления нарисованными блоками. На данный момент они генерируются как экземпляры назначенной ViewModel и фиксируются в списке. Они не связаны напрямую с элементом управления AdvancedImageBox. Однако их необходимо соответствующим образом масштабировать и перемещать, чтобы они оставались соответствующего размера и располагались относительно AdvancedImageBox. Это требует извлечения еще большего количества свойств из элемента управления — коэффициента масштабирования, смещения панорамирования и координат области просмотра.
Координаты области просмотра также не отображаются, поэтому я создал другое пользовательское поведение для их получения (я не прикрепил для этого пример кода, поскольку он эквивалентен приведенному ранее). Как и раньше, это вызывает подавленное исключение о неправильном доступе к потоку.
Мне кажется, что это случай чрезмерного доверия к уже существующему решению. Возможно, создание специального класса элемента управления, адаптированного для этого конкретного использования, является наиболее подходящим способом продолжить?
Надеюсь, я объяснил сценарий ясно. Если что-то не так, пожалуйста, скажите мне. Заранее спасибо.

Подробнее здесь: https://stackoverflow.com/questions/798 ... el-mvvm-co
Ответить

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

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

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

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

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