code behind что это

Сервелат, анимация и старый добрый code-behind

Решил немножко покопаться в Silverlight, да смастерить на нём что-нибудь прикольное. Это прикольное, конечно, должно шевелиться, переливаться и плавно подёргиваться, ибо вебдваноль у нас или где? :). И вот тут мне пришлось столкнуться с неплохой, по сути, системой анимаций в WPF/Silverlight. Покурив MSDN, я бодренько приступил к написанию анимаций в XAML. Одну написал, вторую, третью… А потом мне захотелось сделать так, чтобы они шли в определённой последовательности. И вот тут-то я и понял, что XAML, зараза, очень избыточный. Для описания интерфейсов он подходит идеально: сразу видно, что к чему относится и надобность в визуальном редакторе отпадает чуть менее, чем полностью. Но вот когда пытаешься написать в этом XAMLе какую-то логику, начинает проявляться вся его несуразность. Покурив гугл, я был сильно удивлён тем, что большинство людей упорно пытаются впихнуть в XAML абсолютно всё. Ругаются, путаются в коде, плачут, но продолжают писать. Прямо как те мыши с кактусом, чесслово. И тут мне пришла идея аккуратно описать анимации обычным кодом на C#. Мы, так сказать, олдфаги, рисовали интерфейс прямыми вызовами к WinAPI, неужто нас какие-то анимации испугают? 🙂

В результате получился вот такой портабельный класс AnimationBag. Портабельный он потому, что его безо всяких изменений можно использовать как в WPF, так и в Silverlight.

Как видно из кода, класс предельно простой. Вот пример использования.

Сам класс представляет собой что-то вроде словаря с ключами — именами анимаций и значениями — анимациями. В методе InitAnimations в коллекцию добавляются две анимации, при этом указывается имя, контрол, над которым будет производится действо, свойство этого контрола и сам объект анимации. Его можно создавать ручками, а можно добавить статические хэлперы к уже имеющемуся методу для DoubleAnimation. Кроме всего прочего, метод AddAnimation может принимать два делегата, которые будут выполняться до и после самой анимации. Например, здесь после завершения анимации “fadeOut” сразу запускается “fadeIn”.

В итоге, получился довольно удобный механизм, позволяющий описывать анимации одной строкой кода вместо килобайтов перегруженного XAML.

Источник

Использование Code Behind Окна: допустимо и, если да, то в каких случаях?

Собственно вопрос данной темы это сообщение:

Предыдущие посты приведены, чтобы было понятно откуда взялся этот вопрос.

Прошу воспринимать тему не как «Священные войны», а попытку разобраться в этом вопросе, когда на практике не совсем понятна цель «запрета» на использование CB.
Особенно интересует мнение тех кто реально работает программистом в софтверной компании и знает на практики нюансы коллективной, корпоративной работы, проблемы поддержки выпущенного софта.
Возьму на себя смелость специально «пригласить»: Usaga, Rius, kolorotur, Рядовой, proa33, novikov.ea, escoult.

В каких случаях допустимо приведение указателей/ссылок на дочерний класс к базовому
В каких случаях допустимо приведение указателей/ссылок на дочерний класс к базовому?

В каких случаях оправданно использование локальных классов?
Здравствуйте. Вопрос: в каких случаях оправданно использование локальных классов? Или когда нужно.

Для кнопок, меню и других элементов, у которых есть свойство Command, надо биндить команды.
Для остальных, в зависимости от требуемой функции, или к событиям привязываются команды, или создаются Behavior, AP свойства.

Мы вас правильно поняли, а вы нас не хотите понимать.

Это не шутка, а настоятельная рекомендация (которая для начинающих является ОБЯЗАТЕЛЬНЫМ правилом): НЕ ИСПОЛЬЗУЙТЕ Code Behind.

Все обращения (и тем более создание) к UI элементам в WPF производятся на XAML.
Это основной язык WPF.
C# вспомогательный язык и используется там где надо расширить дефолтные возможности XAML.
На нём создаются: Контекст Данных (ViewModel), конвертеры, AP и DP свойства, Behavior, триггера, различные вспомогательные типы (контейнеры, локаторы, мессенджеры, прокси и т.п.).
Но после создания эти типы используются в XAML.

Добавлено через 3 минуты

Но в некоторых сценариях эта гонка за идеальной архитектурой усложняет код и/или провоцирует перенос логики из View во VM.

Да, это не использование CB, в том неуместном виде, как автор хочет, но и не полный/абсолютный отказ от него.

Можно, конечно, под каждый такой CB-обработчик свой behavior реализовывать во view-слое, но суть примерно та же получается, а сложностей в реализации больше (например, куда более заморочный DI для поведений, чем для конструктора окна/контрола).

Источник

Модель кода в Visual Studio

Пока что мы рассказали только о том, как проектируются простые веб-страницы, и из каких частей состоит интерфейс Visual Studio. Но прежде чем приступать к серьезному кодированию, нужно обязательно разобраться в некоторых базовых деталях модели кода ASP.NET. Поэтому в данной статье речь пойдет о доступных вариантах использования кода для программирования веб-страниц и том, как события ASP.NET привязываются к коду.

Visual Studio поддерживает две модели для кодирования веб-страниц:

Читайте также:  Что значит сунна в исламе

Внутритекстовый код

Эта модель удобна, поскольку позволяет хранить все в одном месте безо всяких излишеств и потому часто применяется для кодирования простых веб-страниц.

Отделенный код (code-behind)

Эта модель подразумевает создание для каждой веб-страницы ASP.NET двух файлов: файла разметки (.aspx) с дескрипторами HTML и дескрипторами элементов управления, и файла кода (.cs) с исходным кодом страницы (при условии, что для программирования веб-страницы применяется язык C#). Такая модель обеспечивает более удобную схему организации, позволяя отделять пользовательский интерфейс от программной логики, что очень важно при создании сложных страниц.

Чтобы лучше понять, в чем состоит разница между моделями внутритекстового и отделенного кода, не помешает рассмотреть какую-нибудь простую страницу. В следующем примере показан код разметки для страницы по имени WebForm1.aspx, который отображает текущее время в текстовой метке и обновляет страницу всякий раз, когда в ней выполняется щелчок на кнопке. В случае использования модели внутритекстового кода эта страница будет выглядеть следующим образом:

Приведенные ниже коды файлов WebForm1.aspx и WebForm1.aspx.cs демонстрируют, как эта же страница будет поделена на две части в случае использования модели отделенного кода:

Единственное реальное отличие между примером с внутритекстовым кодом и примером с отделенным кодом состоит в том, что в последнем случае класс страницы больше не является неявным, а наоборот — объявляется как класс, содержащий все методы страницы.

В целом, модель отделенного кода предпочтительнее использовать для сложных страниц. Хотя модель внутритекстового кода является немного более компактной для небольших страниц, с увеличением объема кода и HTML-разметки с ними становится гораздо проще иметь дело по отдельности. Вдобавок модель отделенного кода является более чистой с концептуальной точки зрения, поскольку явно отображает созданный класс и импортированные пространства имен. И, наконец, она также еще позволяет веб-дизайнеру улучшать разметку страниц, не затрагивая код, написанный разработчиком.

Связывание файлов отделенного кода со страницами

Определять местонахождение связанного кода можно несколькими способами. В более старых версиях ASP.NET было распространено использование атрибута Src для указания на исходный код либо атрибута Inherits для указания на имя скомпилированного класса. Однако обе эти возможности имеют свои индивидуальные особенности.

Например, с помощью атрибута Inherits вы должны предварительно компилировать код, что довольно-таки утомительно (и может вызвать проблемы в командах разработчиков, поскольку стандартной возможностью является компиляция каждой страницы в отдельную DLL-библиотеку сборки). Но реальная проблема состоит в том, что оба подхода вынуждают объявлять каждый веб-элемент управления, который вы собираетесь использовать, с помощью переменной экземпляра. В результате получается большой объем стереотипного кода.

Связывание дескрипторов элементов управления с переменными страниц

При запросе веб-страницы в окне браузера ASP.NET сначала отыскивает связанный с ней файл кода, а затем генерирует объявление переменной для каждого присутствующего в ней серверного элемента управления (т.е. для каждого элемента, у которого имеется атрибут runat=»server»).

Например, предположим, что есть текстовое поле по имени txtInput:

ASP.NET сгенерирует для него следующее объявление переменной экземпляра и объединит его с классом страницы с помощью «волшебного» механизма частичных классов:

Кстати, вы заметите, что переменные элементов управления всегда объявляются с помощью ключевого слова protected (обозначающего защищенный доступ). Все дело в способе, которым ASP.NET использует наследование в модели веб-страниц. Существуют следующие уровни:

Ваш класс отделенного кода (например, WebForm1) наследуется от класса Page, чтобы получить этот базовый набор функциональных возможностей веб-страницы ASP.NET.

Когда вы компилируете свой класс, ASP.NET добавляет в него кое-какой дополнительный код (с помощью «волшебного» механизма частичных классов). В этом генерируемом автоматически коде все имеющиеся на странице элементы управления определяются как защищенные переменные, чтобы можно было получать к ним доступ в коде.

Связывание событий с обработчиками событий

Большая часть кода страницы ASP.NET помещается внутрь обработчиков событий, реагирующих на события веб-элементов управления. С помощью Visual Studio добавить в код обработчик событий можно одним из трех способов:

Ввести его вручную. В этом случае метод добавляется непосредственно в класс страницы. Необходимо указать соответствующие параметры, чтобы сигнатура обработчика событий в точности соответствовала сигнатуре события, которое вы собираетесь обрабатывать. Также понадобится отредактировать дескриптор элемента управления, чтобы он связывал элемент управления с соответствующим обработчиком событий, добавив атрибут OnИмя_события.

Дважды щелкнуть на элементе управления в представлении визуального конструктора. В этом случае Visual Studio создаст обработчик события по умолчанию для этого элемента управления (и соответствующим образом настроит дескриптор элемента управления). Например, двойной щелчок на странице приводит к созданию обработчика события Page.Load, а двойной щелчок на кнопке — обработчика события Click.

Выбрать событие в окне Properties. Выделите элемент управления и щелкните на кнопке с изображением молнии в окне Properties. Вы увидите список всех событий, предоставляемых этим элементом управления. Дважды щелкните на поле рядом с событием, которое собираетесь обработать, и Visual Studio автоматически сгенерирует обработчик события в классе страницы и настроит дескриптор элемента управления:

Читайте также:  чернеют носики у помидор что делать чем обработать

Второй и третий способы наиболее удобны. С другой стороны, третий способ самый гибкий, поскольку позволяет выбрать уже созданный ранее метод в классе страниц. Просто выберите событие в окне Properties и щелкните на стрелке раскрывающегося списка справа. Вы увидите список методов класса, которые соответствуют сигнатуре, ожидаемой этим событием. Затем в списке можно выбрать метод для его подключения, как показано на рисунке выше.

В Visual Studio используется автоматическое образование цепочек событий, как показывает директива Page. Автоматическое образование цепочек событий основано на двух базовых принципах:

Все обработчики событий страницы подключаются автоматически на основании имени обработчика событий. Другими словами, метод Page_Load() автоматически вызывается во время загрузки страницы.

Все обработчики событий элемента управления подключаются с использованием атрибутов в дескрипторе элемента управления. Атрибут носит то же имя, что и событие, но имеет префикс On.

Например, если вы собираетесь обработать событие Click элемента управления Button, необходимо лишь установить атрибут OnClick в дескрипторе элемента управления с именем обработчика событий, который вы собираетесь использовать.

Этот подход служит для создания элементов управления «на лету».

Источник

Как получить удобный доступ к XAML-ресурсам из Code-Behind

Хочу рассказать, как максимально удобно работать с XAML-ресурсами из Code-Behind. В этой статье мы разберемся, как работают пространства имен XAML, узнаем о XmlnsDefinitionAttribute, используем Т4-шаблоны и сгенерируем статичный класс для доступа к XAML-ресурсам.

Введение

При работе с XAML широко используется ResourceDictionary для организации ресурсов: стилей, кистей, конвертеров. Рассмотрим ресурс, объявленный в App.xaml:

При верстке View этот ресурс будет использоваться таким образом:

Когда необходимо использовать тот же самый ресурс из Code-Behind, обычно применяется конструкция:

В ней есть ряд недостатков: строковой идентификатор (ключ) ресурса увеличивает вероятность ошибки, а при большом количестве ресурсов, скорее всего, придется лезть в xaml и вспоминать этот самый ключ. Еще одна неприятная мелочь — приведение к SolidColorBrush т.к. все ресурсы хранятся в виде object.

Эти недостатки могут быть устранены с помощью кодогенерации, в конечном счете получится такая конструкция:

Сразу оговорюсь, что поскольку цель статьи — показать сам подход, для упрощения я заостряю внимание на одном файле App.xaml, но при желании несложные модификации позволят обработать все XAML-ресурсы в проекте и даже разложить их в отдельные файлы.

Если вы не очень знакомы с T4, можете почитать эту статью.

Используем стандартный для T4-заголовок:

Установка hostSpecific=true необходима для того, чтобы иметь доступ к свойству Host класса TextTransformation, от которого наследуется класс шаблона T4. С помощью Host будет осуществляться доступ к файловой структуре проекта и к некоторым другим необходимым данным.

Все ресурсы будут собраны в один статичный класс со статичными readonly Property. Основной скелет шаблона выглядит так:

Все вспомогательные функции и свойства, задействованные в скрипте, объявляются в секции после основного тела скрипта.

Первое свойство VsProject выбирает проект из Solution, в котором лежит сам скрипт:

ProjectDefaultNamespace — пространство имен проекта:

Всю основную работу по сбору ресурсов из XAML выполняет ResourcesFromFile(string filename). Чтобы понять принцип его работы, разберем подробней, как в XAML устроены пространства имен, префиксы, а также как они используются.

Пространства имен и префиксы в XAML

Чтобы однозначно указать на определенный тип в C#, необходимо полностью указать имя типа вместе с пространством имен, в котором он объявлен:

При использовании using приведенную выше конструкцию можно записать короче:

Похожим образом работают и пространства имен в XAML. XAML — это подмножество XML и использует правила объявления пространств имен из XML.

Тип CustomControl в XAML будет объявлен так:

В этом случае XAML-анализатор при разборе документа смотрит на префикс local, который описывает, где искать данный тип.

Зарезервированное имя атрибута — xmlns — указывает на то, что это объявление пространства имен XML. Имя префикса (в данном случае “local”) может быть любым в рамках правил XML-разметки. А также оно вообще может отсутствовать, тогда объявление пространства имен принимает вид:

Такая запись устанавливает пространство имен по умолчанию для элементов, объявленных без префиксов. Если, например, пространство имен CustomNamespace будет объявлено по умолчанию, то CustomControl можно будет использовать без префикса:

Типы, входящие в состав SDK, например, SolidColorBrush объявляются без префикса.

Это возможно благодаря тому, что в корневом элементе XAML-документа объявлено пространство имен по умолчанию:

Атрибут XmlnsDefinitionAttribute переменяется к сборке множество раз описывая пространства имен соответствующие alias-строке:

Стоит заметить, что, если в двух пространствах имен, объединенных под одним alias, есть типы с одинаковым именем, то возникнет коллизия, и XAML-анализатор не сможет разобрать, откуда ему взять искомый тип.

Читайте также:  maui element что за вкус

Конструкция xmlns, как правило, встречается в корневом элементе XAML-документа, но на самом деле достаточно, чтобы xmlns был объявлен хотя бы на том же уровне, на котором используется. В случае с CustomControl возможна такая запись:

Все вышеизложенное понадобится для создания скрипта, который может правильно понять XAML-разметку ReosurceDictionary в котором могут лежать разнородные объекты, входящие в SDK, а также компоненты сторонних библиотек, использующих разные способы объявления пространств имен.

Приступим к основной части

Задача по определению полного имени типа по XAML-тегу возложена на интерфейс ITypeResolver:

Поскольку есть два вида объявления пространства имен, получилось две реализации данного интерфейса:

Другой за случай отвечает XmlnsAliasResolver:

XmlnsAliasResolver регистрирует внутри себя пространства имен, помеченные атрибутом XmlnsDefinitionAttribute с определенным alias, и сборки, в которых они объявлены. Поиск осуществляется в каждом зарегистрированном пространстве имен, пока не будет найден результат.

В реализацию ResolveTypeFullName по желанию можно добавить кэширование найденных типов.

Вспомогательный метод TypeResolvers разбирает XAML-документ, находит все пространства имен и сопоставляет их XML-префиксу, на выходе получается “словарь” Dictionary :

Метод ResourcesFromFile собирает все воедино:

После загрузки XAML-докуменета и инициализации typeResolvers для правильной работы xpath в XmlNamespaceManager добавляется пространство имен schemas.microsoft.com/winfx/2006/xaml, на которое указывают все атрибуты-ключи в ResourceDictionary.

На выходе получается массив структур Resource, содержащих в себе все необходимые данные для кодогенерации:

Ну и напоследок метод, который выводит полученный Resource в виде текста:

Стоит заметить, что свойство Key возвращает значение атрибута-ключа из XAML как есть, и случаи использования ключей с символами, не валидными для объявления свойств в C#, приведут к ошибке. Дабы не усложнять и без того большие куски кода, я намеренно оставляю реализацию получения безопасных для Property имен на ваше усмотрение.

Заключение

Данный скрипт работает в WPF-, Silverlight-, WindowsPhone-проектах. Что касается семейства WindowsRT, UniversalApps, в следующих статьях мы окунемся в XamlTypeInfo.g.cs, поговорим о IXamlMetadataProvider, который пришел на смену XmlnsDefinitionAttribute и заставим скрипт работать с UniversalApps.

Под спойлером вы можете найти полный код скрипта, копируйте в свой проект, используйте с удовольствием.

Источник

Код программной части и XAML в WPF

Этот раздел состоит из следующих подразделов.

Предварительные требования

В этом разделе предполагается, что вы читали XAML в WPF и имеете некоторые базовые знания о среде CLR и объектно-ориентированном программировании.

Code-Behind и язык XAML

Язык XAML включает функции уровня языка, позволяющие связывать файлы кода с файлами разметки с стороны файла разметки. В частности, язык XAML определяет директивуLanguage Features X:Class, директиву x:Subclassи директиву КС:классмодифиер. Точно то, как должен быть создан код и как интегрировать разметку и код, не является частью того, что указывает язык XAML. Она остается в таких платформах, как WPF, для определения способа интеграции кода, использования XAML в моделях приложения и программирования, а также действий сборки или другой поддержки, которые требуются для всех этих платформ.

Код программной части, обработчик событий и требования к разделяемому классу в WPF

Разделяемый класс должен быть производным от типа, который является резервным для корневого элемента.

Обратите внимание на то, что при поведении действия сборки компиляции разметки по умолчанию можно оставить пустое производные в определении разделяемого класса на стороне кода программной части. Скомпилированный результат предполагает, что резервный тип корня страницы будет базисом для разделяемого класса, даже если он не указан. Однако использовать такое поведение не рекомендуется.

Обработчик должен соответствовать делегату для соответствующего события в системе резервных типов.

x:Code

Ограничения встроенного кода

Рекомендуется избегать или ограничивать использование встроенного кода. С точки зрения архитектуры и философии программирования, обеспечение разделения между разметкой и кодом программной части обеспечивает гораздо более отличающиеся роли конструктора и разработчика. На более техническом уровне код, написанный для встроенного кода, может быть неудобным для записи, так как вы всегда пишете в XAML созданный разделяемый класс и можете использовать только сопоставления пространства имен XML по умолчанию. Поскольку нельзя добавлять using инструкции, необходимо полностью определить множество вызовов API. Сопоставления по умолчанию WPF включают большинство, но не все пространства имен CLR, которые есть в WPF сборках. вам придется полностью квалифицировать вызовы типов и членов, содержащихся в других пространствах имен CLR. Кроме того, нельзя определить что-либо за пределами разделяемого класса во встроенном коде, и все сущности кода пользователя, на которые вы ссылаетесь, должны существовать в виде члена или переменной в созданном разделяемом классе. Некоторые функции программирования, такие как макросы или #ifdef глобальные переменные или переменные сборки, также недоступны. Дополнительные сведения см. в разделе Тип данных, встроенный в x:Code.

Источник

Сказочный портал