Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.65/20: Рейтинг темы: голосов - 20, средняя оценка - 4.65
 Аватар для firnen_dragon
25 / 25 / 4
Регистрация: 21.01.2019
Сообщений: 407

Вывод на печать изображения MVVM

09.02.2024, 15:47. Показов 5134. Ответов 69

Студворк — интернет-сервис помощи студентам
Есть у меня в модели такой вот простой метод:
C#
1
2
3
4
5
6
7
8
9
10
public void PrintingQR() 
{
    PrintDialog dlg = new PrintDialog();
    bool? result = dlg.ShowDialog();
 
    if (result.HasValue && result.Value)
    {
        dlg.PrintVisual(qrImage, "Печать картинки");
    }
}
Как я понял PrintDialog не может принимать ни Bitmap ни ImageBitmap, он принимает сами визуальные элементы, а мне нужно распечатать картинку, которая биндится к Image во View, отсюда вопрос, как мне в модель Image прокинуть? Сервис для этого писать чтоб из списка элементов окна его вытаскивать типа этого?
C#
1
2
3
4
5
6
7
8
9
10
11
12
public Visual PrintingQR()
{
    Visual result = null;
    foreach (Window window in Application.Current.Windows)
    {
        if (window.GetType() == typeof(MainWindow))
        {
            result =(window as MainWindow).image;
        }
    }
    return result;
}
Других вариантов пока не придумал, но чую есть способ попроще и красивее, ну или другой вариант печати

Добавлено через 23 минуты
Не PrintDialog, а PrintVisual я имел ввиду...
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
09.02.2024, 15:47
Ответы с готовыми решениями:

Вывод изображения на печать
Подскажите как вывести картинку на печать, именно картинку, про xml, pdf и doc файлы в поиске по находил, а как вывести картинку на печать...

Вывод на печать изображения
Здраствуйте!:)Как можно при печати дать пользовател выбрать принтер и получить контекст принтера для этого принтера?Заранее всем спасибо!:)

Вывод изображения в отчёт на печать
Всем доброго времени суток. Загружаю картинку в базу и вывожу на форму вот так (брал из примеров): &НаКлиенте Процедура...

69
 Аватар для firnen_dragon
25 / 25 / 4
Регистрация: 21.01.2019
Сообщений: 407
09.02.2024, 23:38  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Чья функция ПРЕДСТАВЛЯТЬ данные?
ViewModel
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
09.02.2024, 23:40
Цитата Сообщение от firnen_dragon Посмотреть сообщение
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Чья функция ПРЕДСТАВЛЯТЬ данные?
ViewModel
Нет, конечно.
В любом MV* паттерне представляет данные ПРЕДСТАВЛЕНИЕ (View).
1
 Аватар для firnen_dragon
25 / 25 / 4
Регистрация: 21.01.2019
Сообщений: 407
09.02.2024, 23:42  [ТС]
Получается и все OpenFileDialog должны из ViewModel вызываться?

Добавлено через 1 минуту
Ну я просто не очень понимаю как из View можно вообще что-то вызвать там же просто XAML и все... из Code Behind или как?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
10.02.2024, 00:04
Цитата Сообщение от xellan24rus Посмотреть сообщение
но в этом случае object для ContentControl является свойством которое отображает во view что то. То есть object служит навигационным свойством для ContentControl.
Не совсем понял вас.

Вы имеете ввиду - некое свойство может иметь значения разных типов (или даже одного типа) и View выводит разные представления для разных значений, то это снимает часть противоречий.

Например, обычное int свойство со значениями 1, 2, 3. Они отражают состояния Модели: Disconnect, авторизированный и неавторизированный пользователь (гость). View выводит разные представления для каждого значения. Такая реализация правильна.

Другой пример. В модели есть списки Страны, Регионы, Города. И для переключения между ними реализовано точно такое же свойство в VM. Вот это уже неправильна реализация. Так изменения представления никак не связано с изменением состояния Модели. И такое переключение должно быть реализовано с помощью навигатора в View.

Добавлено через 3 минуты
Цитата Сообщение от firnen_dragon Посмотреть сообщение
Получается и все OpenFileDialog должны из ViewModel вызываться?
Нет. Они должны вызываться в View.

Добавлено через 6 минут
Цитата Сообщение от firnen_dragon Посмотреть сообщение
Ну я просто не очень понимаю как из View можно вообще что-то вызвать там же просто XAML и все... из Code Behind или как?
View - это СЛОЙ представления. И может быть любого типа.
А XAML - это язык разметки WPF.
Если у вас вьюха это консоль или печатная машинка (я застал и такие), то как здесь поможет XAML?

Code Behind, с точки зрения концепции MV* - это такой же код как и XAML. Нет никаких ограничений и тем более запретов на его использование. Такие нюансы - это уже частные детали реализации слоя, которые правилами паттерна не оговариваются.
Другое дело, что отказ от Code Behind это "правила хорошего тона" для разработчиков. В том числе, это может быть закреплено "де-юре" в корпоративных правилах.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
10.02.2024, 09:08
Общие вопросы по разделению функционала между слоями вынесены в тему: Разделение функционала между слоями MVVM на примере создания простого WPF приложения с БД
1
 Аватар для firnen_dragon
25 / 25 / 4
Регистрация: 21.01.2019
Сообщений: 407
12.02.2024, 10:35  [ТС]
Элд Хасп, Правильно я понял, что мне нужно просто сервис написать для PrintDialog и OpenFileDialog, вызывать их в vm и тогда это будет приемлемо?
0
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
12.02.2024, 10:49
firnen_dragon
В рамках MVVM есть два типа ограничений - технические (категорически не могут нарушаться) и идеологические (тут уже зависит от задачи, ну и вопрос весьма холиварный).

Технически, VM-сборка не должна иметь никаких зависимостей от конкретной UI-платформы, т.е. именно на уровне .net-зависимостей. При этом, если нужно реализовать логику показа окна выбора файла или мессаджбокса именно на уровне VM, то да, предоставляете сервис (через интерфейс) и показываете. Реализация и все зависимости при этом остаются во View-слое.

А вот идеологически есть два подхода:
1. Вся логика UI размещается во View-слое.
2. Логика UI частично (или максимально) размещается во VM-слое (но всё так же не имеет зависимостей от UI-библиотек).

P.S.: что лучше/удобнее - зависит от нюансов проекта.
1
 Аватар для xellan24rus
364 / 296 / 55
Регистрация: 08.04.2020
Сообщений: 1,175
12.02.2024, 10:56
kotelok, дополню ответ о
Цитата Сообщение от kotelok Посмотреть сообщение
А вот идеологически есть два подхода:
Лучше почитать соседнюю ветку которая отделилась от этой и стала новой. Там отличный пример как логика c# должна быть разделена. Логика в одном проекте, потребители ее это два других проекта, vm отдельный проект. В проекте со view кроме view вообще ничего нет.

Добавлено через 1 минуту
Цитата Сообщение от firnen_dragon Посмотреть сообщение
Правильно я понял, что мне нужно просто сервис написать для PrintDialog и OpenFileDialog, вызывать их в vm и тогда это будет приемлемо?
Как ответили выше, это будет правильно. Делаете сервис в другом месте в vm его только вызываете. То есть Vm будет потребителем вашего сервиса.
2
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
12.02.2024, 11:06
Цитата Сообщение от xellan24rus Посмотреть сообщение
Логика в одном проекте, потребители ее это два других проекта, vm отдельный проект. В проекте со view кроме view вообще ничего нет.
Речь не об этом, там есть болеет тонкий нюанс.

Бизнес-логика приложения (т.е. слой Model) - это в любом случае отдельный проект, который вообще никак не зависит ни от VM, ни от View. Тут никаких вариантов.

View и ViewModel да, тоже чисто технически разделяются на отдельные сборки, и сборка ViewModel не имеет никаких зависимостей от UI-платформы (т.е. никаких ссылок на WPF/Avalonia/WinForms/Blazor/итп). Тут тоже никаких вариантов.

Однако, открытым остаётся вопрос, какой из слоёв содержит, например, логику отображения мессадж-бокса по какому-то событию (и логику ожидания/обработки ответа пользователя), или же логику навигации между окнами/страницами по действию пользователя - ViewModel или всё же View? Именно логику, не реализацию. Понятно, что реализация отображения MessageBox (или подгрузки контрола) будет где-то во View-слое, т.к. она зависит от конкретной UI-платформы. Но вот откуда этот 'MessageBox' будет вызван? Из code-behind (или ещё какого-то вспомогательного кода) View-слоя, или через интерфейс 'IMessageBox' во ViewModel?

Однозначного ответа тут нет. Равно как и где, например, группировать/форматировать данные для отображения - на стороне View, через мультибиндинг-конвертеры на несколько свойств, или всё же на уровне ViewModel, с последующим простым биндингом на одно свойство. Да и даже преобразование какого-нибудь статуса в цвет, которое вроде как интуитивно должно располагаться во View-слое, может быть перенесено в слой ViewModel, без нарушения зависимостей.
1
 Аватар для firnen_dragon
25 / 25 / 4
Регистрация: 21.01.2019
Сообщений: 407
12.02.2024, 11:12  [ТС]
kotelok, Я просто одного понять не могу View-слой - это где писать то? Я всегда думал, что к View относится XAML окон, кодбихайнд ну и сервисы, в кодбихайнде писать не желательно, остаются только сервисы и XAML, и вы говорите
Цитата Сообщение от kotelok Посмотреть сообщение
Вся логика UI размещается во View-слое.
Я так понимаю предполагается, что где-то еще есть область View-слоя?
0
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
12.02.2024, 11:17
Цитата Сообщение от firnen_dragon Посмотреть сообщение
Грубо говоря это значит что объект OpenFileDialog допустим должен располагаться внутри сервиса?
Это значит, что:
1. В сборке VM у вас в принципе технически не должно быть доступно возможности обратиться к 'OpenFileDialog'.
2. В сборке VM у вас должен быть интерфейс 'IOpenFileDialog' (ну или во вспомогательной сборке, которая тоже ничего про 'OpenFileDialog' не знает).
3. Во View-сборке у вас должна быть реализация 'IOpenFileDialog', которая внутри себя использует 'OpenFileDialog' (или что угодно ещё) и предоставляется во ViewModel-слой через этот самый интерфейс.
1
 Аватар для firnen_dragon
25 / 25 / 4
Регистрация: 21.01.2019
Сообщений: 407
12.02.2024, 11:22  [ТС]
Все понял, спасибо!
1
 Аватар для xellan24rus
364 / 296 / 55
Регистрация: 08.04.2020
Сообщений: 1,175
12.02.2024, 11:35
Цитата Сообщение от kotelok Посмотреть сообщение
Это значит, что:
1. В сборке VM у вас в принципе технически не должно быть доступно возможности обратиться к 'OpenFileDialog'.
2. В сборке VM у вас должен быть интерфейс 'IOpenFileDialog' (ну или во вспомогательной сборке, которая тоже ничего про 'OpenFileDialog' не знает).
3. Во View-сборке у вас должна быть реализация 'IOpenFileDialog', которая внутри себя использует 'OpenFileDialog' (или что угодно ещё) и предоставляется во ViewModel-слой через этот самый интерфейс.
Более простыми словами, делаем интерфейс, реализуем его в Vm ну или в другом месте. Далее наша Vm потребляет реализацию, тем самым она ничего не знает о модели, Vm стала потребителем.
Цитата Сообщение от firnen_dragon Посмотреть сообщение
Я так понимаю предполагается, что где-то еще есть область View-слоя?
Конверторы, кто то запускает окна через них. Но мне кажется это не лучшим подходом.

Добавлено через 8 минут
Цитата Сообщение от firnen_dragon Посмотреть сообщение
, Я просто одного понять не могу View-слой - это где писать то?
Получается в патерне mvvm, view может быть одним проектом. В котором нет ни единой строки c# кода. Vm вы можете как слой из другого проекта. Vm ничего не знает о кодбихайнде, она потребляет модель-бизнес логику, которая может реализовываться хоть где, в проекте с vm или в другой сборке.
Тем самым представим что ваш проект состоит из проекта view, есть vm которая является потребителем модели и наследует интерфейсы или же они реализованы в другом\других классах. Если они реализованы в другом\других классах и другом проекте то этот проект вы можете указать и для сервера или другого приложения. То есть ваша данные никак не связаны и вы можете использовать их хоть где по желанию.
Я понял примерно это так.
1
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
12.02.2024, 11:40
Цитата Сообщение от xellan24rus Посмотреть сообщение
Более простыми словами, делаем интерфейс, реализуем его в Vm ну или в другом месте
Реализуется он НЕ во VM, а где-то в слое View. В слое VM доступен только интерфейс, никаких прямых зависимостей от реализации этого интерфейса слой VM не имеет.
1
 Аватар для xellan24rus
364 / 296 / 55
Регистрация: 08.04.2020
Сообщений: 1,175
12.02.2024, 11:46
Цитата Сообщение от kotelok Посмотреть сообщение
Реализуется он НЕ во VM, а где-то в слое View. В слое VM доступен только интерфейс, никаких прямых зависимостей от реализации этого интерфейса слой VM не имеет.
Но я так понимаю View это только xaml?

Добавлено через 2 минуты
А привычно реализовывать интерфейсы наследуя их в каком то классе. Репозиторий например, отдельный проект который реализует интерфейс. А в Vm используем этот репозиторий. То есть слой Vm остается чист, он только использует модель
1
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
12.02.2024, 12:22
Цитата Сообщение от xellan24rus Посмотреть сообщение
View это только xaml
Нет. View - это всё, что относится к UI конкретной патформы. Например, конвертер из "статуса документа" в "цвет документа" возвращает платформозависимый цвет, а значит он тоже находится во View-слое. Там же, в View-слое, располагается, если требуется, какая-то логика/настройка контролов через code-behind.

Ещё во View-слое иногда размещают и всю логику навигации между окнами/страницами (но это от подхода зависит, оно может и во ViewModel быть через абстракции).
2
 Аватар для xellan24rus
364 / 296 / 55
Регистрация: 08.04.2020
Сообщений: 1,175
12.02.2024, 12:34
kotelok, понял, я узко взял о представление view, но про конверторы писал выше.
Цитата Сообщение от kotelok Посмотреть сообщение
в View-слое, располагается, если требуется, какая-то логика/настройка контролов через code-behind.
Работа с Custom Control к view точно относится.
А вот если в событиях mainwindow работа идет это относится к view, но нарушает mvvm.
Пожалуй нарушать что то надо осознанно, зная что такое mvvm или работать только с view.

Спасибо всем за дискуссию, было интересно)
1
1341 / 920 / 265
Регистрация: 08.08.2014
Сообщений: 2,775
12.02.2024, 12:46
Цитата Сообщение от xellan24rus Посмотреть сообщение
А вот если в событиях mainwindow работа идет это относится к view, но нарушает mvvm.
Ну не всегда:

1. Если в событиях окна (в code-behind) обрабатываются события контролов и реализуется какая-то UI-специфичная логика, то не нарушает.

2. Если в обработчике события 'Click' кнопки в code-behind отображается MessageBox (yes/no) и потом производится обращение к команде/методу ViewModel для, например, удаления записи, то тоже не нарушает.

3. А вот если в code-behind появляется логика, которая работает напрямую с моделью, или сама реализует часть логики модели, то тут уже да, эту логику надо опускать либо в Model, либо во ViewModel.
3
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16165 / 11285 / 2891
Регистрация: 21.04.2018
Сообщений: 33,174
Записей в блоге: 2
12.02.2024, 13:50
Цитата Сообщение от firnen_dragon Посмотреть сообщение
что мне нужно просто сервис написать для PrintDialog и OpenFileDialog, вызывать их в vm и тогда это будет приемлемо?
Диалоги - да.
А вот насколько нужно их из VM вызывать - это уже вопрос.
Я бы на уровне View всё оставил.

Цитата Сообщение от kotelok Посмотреть сообщение
В рамках MVVM есть два типа ограничений - технические (категорически не могут нарушаться) и идеологические (тут уже зависит от задачи, ну и вопрос весьма холиварный).
Скорее - концептуальные и рекомендуемые.

Цитата Сообщение от firnen_dragon Посмотреть сообщение
Я просто одного понять не могу View-слой - это где писать то? Я всегда думал, что к View относится XAML окон, кодбихайнд ну и сервисы, в кодбихайнде писать не желательно, остаются только сервисы и XAML,
View слой, кроме XAML и Code Behind, это ещё: конвертеры, селекторы стилей и шаблонов, Custom Control, Behavoir, расширения разметки, различные контейнеры и прокси (в том числе логаторы, шины сообщений и т.п.), хелперы (в том числе статические обработчики событий), навигаторы, источники данных (в том числе почти таже VM, но с логикой для UI) и ещё многое-многое другое.
1
 Аватар для xellan24rus
364 / 296 / 55
Регистрация: 08.04.2020
Сообщений: 1,175
12.02.2024, 13:51
kotelok, справедливо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
12.02.2024, 13:51

Вывод на 3D-печать векторного изображения брелка.
всем привет! у меня есть векторное изображение и 3д притер,но нет опыта работы в сфере моделирования, мне нужно из этого сделать брелок,как...

[MVVM] Вставка изображения в RichTextBox
Здравствуйте уважаемые программисты. Я решив изучить WPF + MVVM, столкнулся с некоторыми трудностями. У меня есть RichTextBox и не...

Вывод на печать DBGrid из TabSheet на печать в файл ворда
Здравствуйте, не могли бы помочь с выводом на печать? В делфи 10 подключена база и информация выводится в DBGrid на TabSheet. Необходимо...

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

Печать изображения
При отправки изображения на печать сразу происходит печать, но нужно что бы сначала появлялось такое вот окно: как этого добиться? ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины". За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html Задача: . . .
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru