System windows media imaging как подключить
При создании нового проекта WPF в дополнение к создаваемому файлу MainWindow.xaml создается также файл отделенного кода MainWindow.xaml.cs, где, как предполагается, должна находится логика приложения связанная с разметкой из MainWindow.xaml. Файлы XAML позволяют нам определить интерфейс окна, но для создания логики приложения, например, для определения обработчиков событий элементов управления, нам все равно придется воспользоваться кодом C#.
По умолчанию в разметке окна используется атрибут x:Class :
Атрибут x:Class указывает на класс, который будет представлять данное окно и в который будет компилироваться код в XAML при компиляции. То есть во время компиляции будет генерироваться класс XamlApp.MainWindow , унаследованный от класса System.Windows.Window .
Кроме того в файле отделенного кода MainWindow.xaml.cs, который Visual Studio создает автоматически, мы также можем найти класс с тем же именем — в данном случае класс XamlApp.MainWindow. По умолчанию он имеет некоторый код:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace XamlApp < public partial class MainWindow : Window < public MainWindow() < InitializeComponent(); >> >
По сути пустой класс, но этот класс уже выполняет некоторую работу. Во время компиляции этот класс объединяется с классом, сгенерированном из кода XAML. Чтобы такое слияние классов во время компиляции произошло, класс XamlApp.MainWindow определяется как частичный с модификатором partial . А через метод InitializeComponent() класс MainWindow вызывает скомпилированный ранее код XAML, разбирает его и по нему строит графический интерфейс окна.
Взаимодействие кода C# и XAML
В приложении часто требуется обратиться к какому-нибудь элементу управления. Для этого надо установить у элемента в XAML свойство Name .
Еще одной точкой взаимодействия между xaml и C# являются события. С помощью атрибутов в XAML мы можем задать события, которые будут связанны с обработчиками в коде C#.
Итак, создадим новый проект WPF, который назовем XamlApp. В разметке главного окна определим два элемента: кнопку и текстовое поле.
И изменим файл отделенного кода, добавив в него обработчик нажатия кнопки:
using System.Windows; namespace XamlApp < public partial class MainWindow : Window < public MainWindow() < InitializeComponent(); >private void Button_Click(object sender, RoutedEventArgs e) < string text = textBox1.Text; if (text != "") < MessageBox.Show(text); >> > >
Определив имена элементов в XAML, затем мы можем к ним обращаться в коде c#: string text = textBox1.Text .
При определении имен в XAML надо учитывать, что оба пространства имен «http://schemas.microsoft.com/winfx/2006/xaml/presentation» и «http://schemas.microsoft.com/winfx/2006/xaml» определяют атрибут Name , который устанавливает имя элемента. Во втором случае атрибут используется с префиксом x : x:Name . Какое именно пространство имен использовать в данном случае, не столь важно, а следующие определения имени x:Name=»button1″ и Name=»button1″ фактически будут равноценны.
В обработчике нажатия кнопки просто выводится сообщение , введенное в текстовое поле. После определения обработчика мы его можем связать с событием нажатия кнопки в xaml через атрибут Click: Click=»Button_Click» . В результате после нажатия на кнопку мы увидим в окне введенное в текстовое поле сообщение.

Создание элементов в коде C#
Еще одну форму взаимодействия C# и XAML представляет создание визуальных элементов в коде C#. Например, изменим код xaml следующим образом:
Здесь для элемента Grid установлено свойство x:Name , через которое мы можем к нему обращаться в коде. И также изменим код C#:
using System.Windows; using System.Windows.Controls; namespace XamlApp < public partial class MainWindow : Window < public MainWindow() < InitializeComponent(); Button myButton = new Button(); myButton.Width = 100; myButton.Height = 30; myButton.Content = "Кнопка"; layoutGrid.Children.Add(myButton); >> >
В конструкторе странцы создается элемент Button и добавляется в Grid. И если мы запустим приложение, то увидим добавленную кнопку:
Как в WPF просмотреть изображение?
Имеется объект System.Drawing.Bitmap . В WinForms можно было просто использовать PictureBox , чтобы просмотреть изображение. В WPF есть контрол Image , которому Bitmap скормить нельзя. Нашел способ переделки в BitmapImage
using (MemoryStream ms = new MemoryStream()) < bitmap.Save(ms, ImageFormat.Png); ms.Position = 0; BitmapImage bi = new BitmapImage(); bi.BeginInit(); bi.StreamSource = ms; bi.EndInit(); return bi; >ImageBox.Source = logic.NextPage(); // это объект Image
Но ничего не происходит (хотя и ошибок нет). Нужна помощь.
Отслеживать
задан 1 июл 2015 в 17:05
3,471 2 2 золотых знака 20 20 серебряных знаков 42 42 бронзовых знака
А откуда у вас в WPF взялся System.Drawing.Bitmap? Это класс из Windows Forms. В WPF используйте System.Windows.Media.Imaging.BitmapImage.
1 июл 2015 в 17:07
Кстати, да. Проще всего вообще не работать с System.Drawing.Bitmap .
1 июл 2015 в 17:08
@VladD я знаю, что это класс из WinForms. Однако ничего поделать тут не могу — работаю со сторонней сборкой.
1 июл 2015 в 17:10
@RussCoder: Понятно. Сейчас поищу, где-то у меня вроде был код.
1 июл 2015 в 17:11
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.StreamSource = ms;
Пояснение: BitmapImage содержит внутри оптимизацию, которая не грузит данные сразу, а запоминает StreamSource и грузит потом. Но вы уничтожаете MemoryStream (что правильно), поэтому BitmapImage не может позже загрузит данные.
Для будущих поколений:
System.Windows.Media.ImageSource BitmapToImageSource(System.Windows.Bitmap bmp) < using (var ms = new System.IO.MemoryStream()) < bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png); ms.Position = 0; var img = new System.Windows.Media.Imaging.BitmapImage(); img.BeginInit(); img.CacheOption = System.Windows.Media.Imaging.BitmapCacheOption.OnLoad; img.StreamSource = ms; img.EndInit(); return img; >>
System. Windows. Media. Imaging Пространство имен
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Предоставляет типы, используемые для кодирования и декодирования растровых изображений.
Классы
Содержит сведения о кодеках обработки изображений.
Представляет контейнер для кадров растрового изображения. Каждый кадр растрового изображения является объектом BitmapSource. Этот абстрактный класс предоставляет базовый набор функций для всех производных объектов декодеров.
Кодирует коллекцию объектов BitmapFrame в поток изображений.
Представляет данные изображения, возвращаемые декодером и принимаемые кодировщиками.
Предоставляет специальный объект BitmapSource, оптимизированный для загрузки изображений с помощью языка XAML.
Предоставляет поддержку чтения метаданных из растрового изображения и записи метаданных в растровое изображение.
Предоставляет заполнитель для элементов метаданных, которые нельзя преобразовать из C# в базовый тип данных, хранящий метаданные. Большой двоичный объект преобразуется в массив байтов для сохранения содержимого.
Определяет доступную цветовую палитру для поддерживаемого типа изображений.
Определяет несколько цветовых палитр, часто используемых растровыми изображениями.
Определяет размерные атрибуты кэшированного растрового изображения. Масштабирование растрового изображения выполняется на основе значений, которые определяются этим классом.
Представляет один постоянный набор пикселей определенного размера и разрешения.
Определяет декодер для изображений, закодированных как растровые (BMP).
Определяет кодировщик, используемый для кодирования изображений в формате BMP.
Предоставляет функциональность кэширования для BitmapSource.
Изменяет пространство цвета для BitmapSource.
Предоставляет данные для событий DownloadProgress и DownloadProgress .
Предоставляет функциональные возможности преобразования формата пикселей для BitmapSource.
Определяет декодер для изображений, закодированных в формате GIF.
Определяет кодировщик, используемый для кодирования изображений в формате GIF.
Определяет специализированный декодер для изображений, кодированных в формате значков (файлов с расширением ICO).
Позволяет выполнять обновления на месте для существующих блоков BitmapMetadata.
Определяет декодер для изображений, закодированных в формате JPEG.
Определяет кодировщик, используемый для кодирования изображений в формате JPEG.
Определяет декодер, который требует отложенного создания растрового изображения, например асинхронной загрузки изображения.
Определяет декодер для изображений, закодированных в формате PNG.
Определяет кодировщик, используемый для кодирования изображений в формате PNG.
Преобразует объект Visual в растровое изображение.
Определяет декодер для изображений, закодированных в формате TIFF.
Определяет кодировщик, используемый для кодирования изображений в формате TIFF.
Масштабирует и поворачивает объект BitmapSource.
Определяет декодер для закодированных изображений Microsoft Windows Media Photo.
Определяет кодировщик, используемый для кодирования изображений Microsoft Windows Media Photo.
Предоставляет объект BitmapSource, в который можно осуществить запись и обновить.
Перечисления
Указывает, как растровое изображение использует преимущества кэширования в памяти.
Указывает параметры инициализации для точечных рисунков.
Указывает, чередуются ли строки изображения в формате PNG во время кодирования.
Указывает поворот, применяемый к растровому изображению.
Указывает возможные схемы сжатия для растровых изображений в формате TIFF.
Обратная связь
Были ли сведения на этой странице полезными?
Обратная связь
Отправить и просмотреть отзыв по
Классы отделенного кода XAML

Язык XAML позволяет конструировать пользовательский интерфейс, но для создания функционирующего приложения необходим способ подключения обработчиков событий. XAML позволяет легко это сделать с помощью атрибута Class, показанного ниже:
Префикс пространства имен «x» помещает атрибут Class в пространство имен XAML, что означает более общую часть языка XAML. Фактически атрибут Class сообщает анализатору XAML, чтобы он сгенерировал новый класс с указанным именем. Этот класс наследуется от класса, именованного элементом XML. Другими словами, этот пример создает новый класс по имени MainWindow, который наследуется от базового класса Window.
Класс MainWindow генерируется автоматически во время компиляции. И здесь начинается самое интересное. Вы можете предоставить часть класса MainWindow, которая будет объединена с автоматически сгенерированной частью этого класса. Указанная вами часть — блестящий контейнер для кода обработки событий.
Эта «магия» возможна благодаря средству C#, известному под названием частичные классы (partial class). Частичные классы позволяют разделить класс на две или более отдельных части во время разработки, которые соединяются вместе в скомпилированной сборке. Частичные классы могут применяться во многих сценариях управления кодом, но более всего удобны, когда код должен объединяться с файлом, сгенерированным визуальным конструктором.
Среда Visual Studio оказывает помощь, автоматически создавая частичный класс, куда можно поместить код обработки событий. Например, при создании приложения по имени WpfApplication1, содержащего окно по имени MainWindow. Visual Studio начнет с создания следующего базового каркаса класса:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApplication1 < /// /// Логика взаимодействия для MainWindow.xaml /// public partial class MainWindow : Window < public MainWindow() < InitializeComponent(); >> >
Во время компиляции приложения код XAML, определяющий пользовательский интерфейс (такой как MainWindow.xaml), транслируется в объявление типа CLR, объединенного с логикой файла класса отделенного кода (подобного MainWindow.xaml.сs), формируя один общий модуль.
Метод InitializeComponent()
В данный момент класс MainWindow не содержит реальной функциональности. Однако он включает одну важную деталь — конструктор по умолчанию, который вызывает метод InitializeComponent(), когда создается экземпляр класса.
Метод InitializeComponent() играет ключевую роль в приложениях WPF. По этой причине никогда не следует удалять вызов InitializeComponent() из конструктора окна. В случае добавления к классу окна другого конструктора обязательно предусмотрите в нем вызов InitializeComponent().
Метод InitializeComponent() не видим в исходном коде, потому что генерируется автоматически при компиляции приложения. По существу все, что делает InitializeComponent() — это вызов метода LoadComponent() класса System.Windows.Application. Метод LoadComponent() извлекает код BAML (скомпилированный XAML) из сборки и использует его для построения пользовательского интерфейса.
При разборе BAML он создает объекты каждого элемента управления, устанавливает их свойства и присоединяет все обработчики событий.
Именование элементов
Есть еще одна деталь, которая должна приниматься во внимание. В классе отделенного кода часто требуется программно манипулировать элементами управления. Например, необходимо читать либо изменять свойства, а также присоединять или отсоединять обработчики событий на лету. Чтобы обеспечить такую возможность, элемент управления должен включать XAML-атрибут Name. В предыдущем примере элемент Grid не содержит атрибут Name, поэтому манипулировать им в отделенном коде не получится.
Ниже показано, как назначить имя элементу Grid:
Можно внести это изменение в документ XAML вручную или выбрать элемент в визуальном конструкторе Visual Studio и установить свойство Name в окне Properties (Свойства).
В обоих случаях атрибут Name сообщит анализатору XAML о необходимости добавить поле следующего вида к автоматически сгенерированной части класса MainWindow:
private System.Windows.Controls.Grid MyGrid;
Теперь с этим элементом можно взаимодействовать в коде класса MainWindow указывая имя MyGrid:
MessageBox.Show("Размер сетки: " + MyGrid.ActualWidth + "x" + MyGrid.ActualHeight);
Такая техника мало что дает простому примеру, но становится намного важнее, когда требуется читать значения из элементов управления вводом, таких как текстовые поля и списки.
Показанное ранее свойство Name является частью языка XAML и используется для того, чтобы помочь в интеграции класса отделенного кода. Из-за того, что многие классы определяют собственное свойство Name, происходит некоторая путаница. (Примером может служить базовый класс FrameworkElement, от которого наследуются все элементы WPF.) Анализаторы XAML элегантно справляются с этой проблемой. Можно либо установить XAML-свойство Name (используя префикс х:), либо свойство Name, относящееся к действительному элементу (опустив префикс).
В любом случае результат один и тот же — указанное имя используется в файле автоматически сгенерированного кода и применяется для установки свойства Name.
Это значит, что следующая разметка эквивалентна тому, что вы уже видели:
Такой трюк работает только в том случае, если включающий свойство Name класс оснащен атрибутом RuntimeNameProperty. Атрибут RuntimeNameProperty указывает на то, какое свойство должно трактоваться в качестве имени экземпляра этого типа. (Очевидно, обычно таким свойством является Name.) Класс FrameworkElement содержит атрибут RuntimeNameProperty, так что никаких проблем нет.
В традиционном приложении Windows Forms каждый элемент управления имеет имя. В приложении WPF такого требования нет. Однако при создании окна перетаскиванием элементов на поверхность визуального конструктора Visual Studio каждому элементу назначается автоматически сгенерированное имя. Таково соглашение. Если вы не собираетесь взаимодействовать с элементом в коде, то можете удалить атрибут Name из кода разметки.
Управление объявлениями классов и переменных-членов
Многие из этих ключевых полей вы увидите в действии там, где они понадобятся. Давайте в качестве простого примера рассмотрим следующее определение XAML , в котором используются ключевые слова ClassModifier и FieldModifier, а также x:Name и x:Class:
По умолчанию все определения сгенерированных типов C#/XAML в WPF являются внутренними (internal), а члены — общедоступными (public). Однако на основе показанного определения XAML результирующий автоматически сгенерированный файл содержит тип класса internal с public-членом Button:
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")] internal partial class MainWindow : System.Windows.Window, System.Windows.Markup.IComponentConnector < #line 6 "..\..\..\MainWindow.xaml" [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] internal System.Windows.Controls.Grid MyGrid; #line default #line hidden /// /// Btn1 Name Field /// #line 8 "..\..\..\MainWindow.xaml" [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")] public System.Windows.Controls.Button Btn1;