Форум программистов, компьютерный форум, киберфорум
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. Показов 5109. Ответов 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,172
Записей в блоге: 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,172
Записей в блоге: 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,172
Записей в блоге: 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,172
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru