понедельник, 10 октября 2011 г.

Code Contracts и Visual Studio Express

На сайте DevLabs (разработчиков Code Contracts) написано, что Visual Studio Express не поддерживается. Мне это показалось весьма странным, с учетом того, что System.Diagnostics.Contracts включен в .Net Framework 4. Конечно, Express версии не поддерживают PlugIn’ов, но ведь это совсем не повод, чтобы отказываться от использования CodeContract’ов, тем более, что все равно нужно выкачивать и устанавливать на машину разработчика то, что и называется CodeContracts. Установка содержит

  • ccrewrite утилита для осуществления проверки во время выполнения;
  • ccdoc утилита для генерации документации;
  • набор бибилиотек для .Net Framework’a 3.5 (по-моему, 3’й не поддерживается)

Премиум также содержит cccheck статический анализатор времени компиляции;

После установки в Visual Studio, в версиях выше Professional, в свойствах проекта появляется еще одна закладка: “Code Contracts”

 

image

Если отжать Perform Runtime Checking, то контракты начинаю срабатывать.

Если после этого открыть проект в Express версии (или в #Develope ), то контракты продолжат работать, не смотря на то, что закладки “Code Contacts” в свойствах проекта не появляется.

Итак, что же изменилось? А изменяется вот что: в файле проекта добавляются строки описывающие поведение контрактов.

Чтобы увидеть изменения нужно открыть сам файл проекта (.csproj для С#) в текстовом виде:

  • В VS Professional и выше: выгружаем проект в Solution Explorer,  правой кнопкой щелкаем на проект и выбираем Edit ProjectName.csproj;
  • в Express версии, просто лезем в папку с проектом и открываем любым простейшим текстовым редактором.

В каждую PrepertyGroup соответствующую вариантам сборки (X86/Debug/Release) добавились следующие строчки:

<CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
<CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
<CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
<CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
<CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
<CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
<CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
<CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
<CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
<CodeContractsEnumObligations>False</CodeContractsEnumObligations>
<CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
<CodeContractsRunInBackground>True</CodeContractsRunInBackground>
<CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
<CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
<CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
<CodeContractsCustomRewriterAssembly />
<CodeContractsCustomRewriterClass />
<CodeContractsLibPaths />
<CodeContractsExtraRewriteOptions />
<CodeContractsExtraAnalysisOptions />
<CodeContractsBaseLineFile />
<CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
<CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
<CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly>
<CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>

Привожу, за что какие параметры отвечают:

  • CodeContractsEnableRuntimeChecking: если значение установлено в true, ccrewrite будет вживлять в проект проверку условий контракта. Фактически проверки выполнения контрактов начинаются с установки  этого значения и для того чтобы разобраться с использованием достаточно включить только его; 
  • CodeContractsRuntimeCheckingLevel: устанавливает уровни использования контрактов, то есть можно включить проверку только пред или постусловий. Принимаемые значения: Full, Pre and Post, Preconditions, ReleaseRequires или None;
  • CodeContractsRuntimeThrowOnFailure: если установлено в true, то контракт будет выбрасывать исключение. Если false, то проверка контракта будет вести себя как Debug.Assert;
  • CodeContractsRuntimeOnlyPublicSurface: если установлено true, то обрабатываются только публичные методы;
  • CodeContractsRuntimeCallSiteRequires: когда установлено true, реврайтер внедряет контракты в вызывающие ваш код приложения; ;
  • CodeContractsReferenceAssembly: принимает значения {Build, DoNotBuild, None}. Если выставить в Build, то создается дополнительная сборка с набором контрактов для этого проекта. Это нужно если на ваш проект ссылается еще один и ему нужно видеть, какие контракты используются или если вы хотите генерировать документацию по контрактам;
  • CodeContractsEmitXMLDocs: если установлено в true вместе с CodeContractsReferenceAssembly, генерируемая документацию к сборке будет содержать описание контрактов;
  • CodeContractsCustomRewriterAssembly: указывает пусть к сборке содержащей свою реализацию методов реврайтера;
  • CodeContractsCustomRewriterClass: содержит имя класса в котором реализованы методы, используется вместе с CodeContractsCustomRewriterAssembly;
  • CodeContractsLibPaths: здесь указываются через точку с запятой  пути к дополнительным сборкам содержащим контракты;
  • CodeContractsRunCodeAnalysis: значение включает статическую проверку кода собираемого проекта;
  • CodeContractsNonNullObligations: когда установлено true, статический анализатор будет пытаться проверять все ссылки на корректность;
  • CodeContractsBoundsObligations: когда установлено true, статический анализатор будет пытаться проверять корректность указания границ массивов;
  • CodeContractsArithmeticObligations: когда установлено true, статический анализатор будет пытаться проверять корректность математических операций, таких как деление на ноль;
  • CodeContractsRedundantAssumptions: когда установлено true, статический анализатор будет выдавать warning’и при “очевидных сравнениях” (не знаю как правильно перевести Redundant Assumptions) ;
  • CodeContractsRunInBackground: если установлено в true,  статический анализатор работает в фоновом процессе, не блокируя сборку проекта;
  • CodeContractsExtraAnalysisOptions: используется для передачи дополнительных параметров статического анализатора;
  • CodeContractsRuntimeSkipQuantifiers: если установлено в true, то некоторые контракты содержащие вызовы Contract.ForAll и Contract.Exists пропускаются. Это дает большую разницу в производительности;
  • CodeContractsEnumObligations: если установлено в true, статический анализатор проверяет границы перечислений; 
  • CodeContractsShowSquigglies: включает подчеркивание волнистой линией ошибок;
  • CodeContractsUseBaseLine: включает так называемую БазовуюЛинию. Она используется для того, чтобы статический анализатор мог отслеживать предупреждения только в изменяемом коде. При включении генерируется файл содержащий предупреждения и при последующих компиляциях они не отображаются;
  • CodeContractsBaseLineFile: имя файла в который записываются предупреждения;
  • CodeContractsExtraRewriteOptions: содержит дополнительные параметры для ccrewrite;
  • CodeContractsCacheAnalysisResults: включает кэширование статическим анализатором результатов;
  • CodeContractsAnalysisWarningLevel:  устанавливает уровень эвристики статического анализатора.

Большинство этих параметров вносить не обязательно. Параметры, которые относятся к статическому анализатору можно точно откинуть, а остальные, за исключением CodeContractsEnableRuntimeChecking имеют вполне рабочие значения по умолчанию. Если вы хотите избавить свой проект от нагромождений if…throw,то достаточно использовать  CodeContractsEnableRuntimeChecking.

Например.

Создаем в Visual Studio Express новый проект консольного приложения с таким кодом:

static void Main(string[] args)
{
    PrintMessage("Привет");
    Console.ReadLine();
}

static void PrintMessage(string str)
{
    Contract.Requires(str.Length > 10,"Message to short");
    Console.WriteLine("Сообщение: {0}",str);
}

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

Сохраняем, закрываем VS Express, вносим изменения в файл проекта, снова открываем проект в VS Express.

image

Контракты начинают срабатывать.

вторник, 2 августа 2011 г.

Сохранение порядка сортировки выборки в Linq

На MSDN’овском форуме задали вопрос о сохранении порядка сортировки выборки при использовании Linq. Задача достаточно типовая, поэтому решил написать небольшой мануал, как это сделать используя Dynamic Linq. Для упрощения пусть данные отображается у нас в DataGrid’e и сортируются нажатием мышкой на заголовок столбцов.

Dynamic Linq

Библиотека Dynamic Linq  входит в набор примеров кода для Visual Studio 2008 (C#, VB). После выкачивания можно найти исходный код, документацию и пример использования в папке \LinqSamples\DynamicQuery.

Проект с примером использования отлично собирается как под .Net Framework 3.5, так и под 4.0.  Сам код библиотеки вынесен в namespace System.Linq.Dynamic и находится в файле Dynamic.cs. Для использования можно скопировать код к себе в проект или создать отдельный проект с библиотекой.

Использование

Итак у нас есть форма, на ней DataGrid с гордым именем dataGrid1.

Простой класс:

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string NickName { get; set; }
    public DateTime BirthDate { get; set; }
}

При инициализации формы подсовываем Grid’у в качестве источника данных массив Person:

var persons = new Person[] 
{
    new Person{FirstName = "Сидр", LastName = "Сидоров", NickName = "sid", BirthDate = DateTime.Today.AddYears(-22)},
    new Person{FirstName = "Петр", LastName = "Петров", NickName = "pit", BirthDate = DateTime.Today.AddYears(-21)},
    new Person{FirstName = "Иван", LastName = "Иванов", NickName = "ian", BirthDate = DateTime.Today.AddYears(-20)},
};
this.dataGrid1.ItemsSource = persons;

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

Итак, приступим.

Первое, что нам нужно сделать, это перенести код библиотеки Dynamic Linq  к себе в проект. Это можно сделать двумя способами:

  1. Создать класс и скопировать код из полученного ранее проекта;
  2. Сразу добавить файл в себе в проект (в Solution Explorer’e щелкнуть право кнопкой на проект, и выбрать Add->Existing Item).

У DataGrid’а добавляем в обработчик события Sorting код, который будет сохранять поле и порядок сортировки в конфигурационном файле

private void dataGrid1_Sorting(object sender, DataGridSortingEventArgs e)
{
    IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly();
    using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("LastSort.txt", FileMode.Create, store))
    {
        using (StreamWriter writer = new StreamWriter(stream))
        {
            writer.WriteLine(String.Format("{0} {1}", e.Column.SortMemberPath,
                (e.Column.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending));
        }
    }
}

Небольшое пояснение по поводу IsolatedStorage
IsolatedStorage – это механизм позволяющий сохранять данные в “виртуальные” папки в зависимости от выбранной области ограничения видимости. Использованная функция GetUserStoreForAssembly() возвращает нам “путь” который уникален для пользователя  и Assembly, т.е. другие приложения и пользователи не будут иметь доступ к файлу LastSort.txt в котором хранятся данные об используемом порядке сортировки.

Небольшое пояснение по поводу (e.Column.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending
Дело в том, что Column.SortDirection является Nullable, то есть кроме ListSortDirection.Ascending и ListSortDirection.Descending принимает еще и значение NULL, которое и является значением по умолчанию. Помимо этого в  DataGridSortingEventArgs e содержится предыдущее состояние сортировки, поэтому приходится использовать такую конструкцию.

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

private void Window_Closing(object sender, CancelEventArgs e)
{
    foreach (var c in this.dataGrid1.Columns)
    {
        if (c.SortDirection.HasValue)
        {
            IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly();
            using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("LastSort.txt", FileMode.Create, store))
            {
                using (StreamWriter writer = new StreamWriter(stream))
                {
                    writer.WriteLine(String.Format("{0} {1}", c.SortMemberPath, c.SortDirection));
                }
            }
            break;
        }
    }
}

Пишем функцию которая выдергивает значение из файла в изолированном хранилище

private string GetLastSort()
{
    IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForAssembly();
    using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("LastSort.txt", FileMode.OpenOrCreate, store))
    {
        using (StreamReader reader = new StreamReader(stream))
        {
            return reader.ReadLine() ?? "NickName Descending";
        }
    }
}

После этого меняем подключение данных для DataGrid’а на

this.dataGrid1.ItemsSource = persons.AsQueryable<Person>().OrderBy(GetLastSort()).Select("new (FirstName, LastName, NickName, BirthDate)");

среда, 20 апреля 2011 г.

Экзамен 70-599: Pro: Designing and Developing Windows Phone 7 Applications, Часть 5: Designing the User Interface and User Experience

>>В начало

Designing the User Interface and User Experience (23%)

  • Design for separation of concerns.
    • This objective may include but is not limited to: presentation patterns that use view models, MVVM
  • Design Windows Phone 7 control usage.
    • This objective may include but is not limited to: design control usage as described in UI Design and Interaction Guide for Windows Phone 7; design proper use of PanoramaControl and PivotControl; choose when to use the Panorama Control and PivotControl; recommend when to use ApplicationBar
  • Recommend keyboard layout for a given situation.
    • This objective may include but is not limited to: InputScope property
  • Design for system themes, accent color, and screen orientation.
    • This objective may include but is not limited to: built-in styles that use system themes and accent colors, ApplicationBar icons (size, transparency), landscape, portrait

Ссылки:

Designing the User Interface and User Experience (23%)

RU links: Video (EN)

Экзамен 70-599: Pro: Designing and Developing Windows Phone 7 Applications, Часть 4: Designing the Application Architecture

>>В начало

Designing the Application Architecture (21%)

  • Design for threading.
    • This objective may include but is not limited to: use of the composition thread
  • Monitor and tune performance.
    • This objective may include but is not limited to: frame rate counter; cache visualization; redraw regions; bitmap caching; memory usage limitations; plan for power consumption; tune bandwidth consumption; performance counters
  • Manage the application life cycle.
    • This objective may include but is not limited to: tombstoning; response to PhoneApplicationService events (Launching, Activated, Deactivated, Closing)
  • Prepare the application to meet Windows Phone 7 marketplace requirements.
    • This objective may include but is not limited to: Windows Phone 7 Application Certification Requirements; design for localization and globalization; plan for trial versions; work with WMAppManifest.xml; design for icon requirements for marketplace

Ссылки:

Designing the Application Architecture (21%)

RU Links:

Other links:

Video (EN):

Экзамен 70-599: Pro: Designing and Developing Windows Phone 7 Applications, Часть 3: Working with Platform APIs, Tasks, and Choosers

>>В начало

Working with Platform APIs, Tasks, and Choosers (21%)

  • Design and implement sensor interaction.
    • This objective may include but is not limited to: choose which sensors are appropriate for your application; design location awareness (when to use different levels of GeopositionAccuracy); location awareness system setting
  • Plan for and implement the use of Tasks and Choosers.
  • Plan for and implement multitouch and gestures.
    • This objective may include but is not limited to: manipulation events (ManipulationStarted, ManipulationCompleted, ManipulationDelta)
  • Design and implement application navigation.
    • This objective may include but is not limited to: pass parameters (NavigationContext API), manipulate the navigation stack (NavigationService API), use of the Back button, PhoneApplicationPage class and PhoneApplicationFrame class and the difference between these two classes

Ссылки:

Working with Platform APIs, Tasks, and Choosers (21%)

RU Links:

EN Links:

Video (EN):

Экзамен 70-599: Pro: Designing and Developing Windows Phone 7 Applications, Часть 2: Designing and Implementing Notification Strategies

>>В начало

Designing and Implementing Notification Strategies (17%)

  • Plan for and implement push notifications in the application.
    • This objective may include but is not limited to: choose method for notifying user of application’s state/status (tile, toast, RAW); respond to notifications; registration for notifications
  • Plan for and implement push notifications on the server.
    • This objective may include but is not limited to: when to use toast, tile, and raw; plan for receiving the unique device URL
  • Create and update live tiles.
    • This objective may include but is not limited to: update background image, numbers, and text

Ссылки:

Designing and Implementing Notification Strategies (17%)

RU Links: EN Links: Video (EN):

Экзамен 70-599: Pro: Designing and Developing Windows Phone 7 Applications, Часть 1: Designing Data Access Strategies

>>В начало

Designing Data Access Strategies (19%)

  • Send and receive data.
    • This objective may include but is not limited to: design connection mechanisms for communicating with external web services; plan how to consume and parse data from web services (for example, WCF and WS*); ensure a trusted transfer of data to and from a phone
  • Design a data storage strategy.
    • This objective may include but is not limited to: differentiate between persistent and transient data; determine when to use isolated storage; plan for size limitations of isolated storage; design cloud-based storage
  • Plan for bandwidth limitations and implement network connectivity detection.
    • This objective may include but is not limited to: plan for disconnected scenarios; plan for low network bandwidth

Ссылки:

Designing Data Access Strategies (19%)

RU Links: Video (EN):

Экзамен 70-599: Pro: Designing and Developing Windows Phone 7 Applications, Часть 0

Итак приступаем к подготовке к экзамену по Windows Phone 7.

Пока анонсирована только Beta версия, но к релизу экзамена, обычно, ничего не меняется.

Страница экзамена: тут.

Требования к знаниям:

Designing Data Access Strategies (19%)

  • Send and receive data.
  • Design a data storage strategy.
  • Plan for bandwidth limitations and implement network connectivity detection.

Designing and Implementing Notification Strategies (17%)

  • Plan for and implement push notifications in the application.
  • Plan for and implement push notifications on the server.
  • Create and update live tiles.

Working with Platform APIs, Tasks, and Choosers (21%)

  • Design and implement sensor interaction.
  • Plan for and implement the use of Tasks and Choosers.
  • Plan for and implement multitouch and gestures.
  • Design and implement application navigation.

Designing the Application Architecture (21%)

  • Design for threading.
  • Monitor and tune performance.
  • Manage the application life cycle.
  • Prepare the application to meet Windows Phone 7 marketplace requirements.

Designing the User Interface and User Experience (23%)

  • Design for separation of concerns.
  • Design Windows Phone 7 control usage.
  • Recommend keyboard layout for a given situation.
  • Design for system themes, accent color, and screen orientation.

Основные ссылки:

понедельник, 21 марта 2011 г.

WPF DataGrid и раскраска (выделение цветом) ячеек и строк (HOWTO)

Иногда возникает необходимость выделить цветом какие-нибудь данные в DataGrid’е. Давайте рассмотрим, как это можно сделать в WPF.
Для примера создадим класс Person
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

Пишем небольшую заполнялку тестовых данных:
private List<Person> GenerateSampleData()
{
    Random r = new Random();
    List<Person> personList = new List<Person>();
    for (int i = 1; i <= 100; i++)
    {
        personList.Add(new Person { Id = i, Name = String.Format("Person Name {0}", i), Age = r.Next(60) });
    }
    return personList;
}

Кидаем на поверхность окна DataGrid и в конструкторе формы заполняем данными:
this.dataGrid1.ItemsSource = GenerateSampleData();

И получаем вот такую милую/унылую таблицу.


Допустим, у нас стоит задача выделить цветом те “персоны”, возраст которых не достиг 16 лет.


1.1. В определение окна добавляем ссылку на пространство имен текущего проекта

xmlns:local="clr-namespace:DataGridColor"
 

1.2. Создаем конвертер, который будет преобразовывать возраст в кисть, которой будем закрашивать фон
 
class AgeToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Все проверки для краткости выкинул
        return (int)value <= 16 ? 
            new SolidColorBrush(Colors.OrangeRed)
            : new SolidColorBrush(Colors.White);
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new Exception("The method or operation is not implemented.");
    }
}


1.3. В ресурсах окна определяем ключ конвертера
<local:AgeToColorConverter x:key="AgeToColorConverter">

1.4. И там же, в ресурсах окна, объявляем стиль, TargetType у которого будет DataGridRow.

<Style TargetType="{x:Type DataGridRow}">
    <Setter Property="Background" Value="{Binding Age, Converter={StaticResource AgeToColorConverter}}" />
</Style>

В результате получаем вот такую полосатую таблицу:



А что если нужно выделять цветом не всю строку, а только отдельные ячейки в колонке. Для примера, нужно выделить ячейки с идентификатором меньше либо равно 16.

Эта задача решается похожим способом.

2.1. Добавляем в проект еще один конвертер
class IdToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Все проверки для краткости выкинул
        return (int)value <= 16 ?
            new SolidColorBrush(Colors.Yellow)
            : new SolidColorBrush(Colors.Green);
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new Exception("The method or operation is not implemented.");
    }
}

2.2 Присваивам ключ
<local:IdToColorConverter x:Key="IdToColorConverter" />

2.3. Добавляем в ресурсы окна еще один стиль, TargetType’ом у которого является  DataGridCell. Так же стилю присваиваем ключ посредством указания x:Key="IdStyle", иначе стиль будет применен для всех ячеек во всех таблицах (а ведь нам этого не нужно).
<Style x:Key="IdStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="{Binding Id, Converter={StaticResource IdToColorConverter}}" />
</Style> 


2.4. И для колонки, в которой хотим использовать раскраску отличную от всей строки указываем CellStyle:

<DataGridTextColumn Header="ID" Width="50" 
                    Binding="{Binding Id}" 
                    CellStyle="{StaticResource IdStyle}"/>


2.5. Если раздражает, что цвет Border’a ячейки теперь берется из цвета Background’а строки,  модифицируем стиль для ячейки устанавливая закраску Border’a белым цветом
<Style x:Key="IdStyle" TargetType="{x:Type DataGridCell}">
    <Setter Property="Background" Value="{Binding Id, Converter={StaticResource IdToColorConverter}}" />
    <Setter Property="BorderBrush"  Value="White" />
</Style>






Собственно, чтобы привлечь внимание к определенной ячейке не обязательно делать из DataGrid’а приведенного попугая, достаточно подкрашивать Border присваивая BorderBrush’у акцентирующую кисть.

Если есть вопросы – задавайте, будем разбираться вместе.

UPDATE: Если нужно раскрашивать строчки в зависимости от значений нескольких полей в таблице, то следует использовать MultiBinding и реализовывать интерфейс IMultiValueConverter. Для примера реализован вариант запрошенный io, когда нужно выделить строку, если идентификатор меньше 10 или возраст меньше 16.
Пример использования MultiBinding'а:
<Style TargetType="{x:Type DataGridRow}">
  <Setter Property="Background">
    <Setter.Value>
      <MultiBinding Converter="{StaticResource MultiBindingConverter}">
        <Binding Path="Id"/>
        <Binding Path="Age"/>
      </MultiBinding>
    </Setter.Value>
  </Setter>
</Style>

Пример реализации IMultiValueConverter'а:
    class MultiBindingConverter:IMultiValueConverter

    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return ((int)values[0] <10 || (int)values[1]<16) ? 
                new SolidColorBrush(Colors.OrangeRed)
                : new SolidColorBrush(Colors.White);
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

PS. Выложил исходники.

среда, 16 марта 2011 г.

Подготовка к экзамену 70-511: TS: Windows Applications Development with Microsoft .NET Framework 4. Часть 5: Stabilizing and Releasing a Solution

>>В начало

Требования к знаниям:

  • Implement a WPF test strategy.
    This objective may include but is not limited to: automation peer, UI automation, IntelliTrace
  • Debug XAML by using the WPF Visualizer.
    This objective may include but is not limited to: accessing the Visualizer, drilling down into the visual tree, viewing and changing properties
    This objective does not include: setting a breakpoint and stepping through code
  • Debug WPF issues by using PresentationTraceSources.
    This objective may include but is not limited to: animation, data binding, dependency properties
  • Configure a ClickOnce deployment.
    This objective may include but is not limited to: configuring the installation of a WinForms, WPF, or XBAP application by using ClickOnce technology; choosing appropriate settings to manage upgrades
  • Create and configure a Windows Installer project.
    This objective may include but is not limited to: configuring a setup project to add icons during setup, setting deployment project properties, configuring conditional installation based on operating system versions, setting appropriate Launch Conditions based on the .NET Framework version, adding custom actions to a setup project, adding error-handling code to a setup project
  • Configure deployment security settings.
    This objective may include but is not limited to: configuring and integrating UAC by using ClickOnce deployments; setting appropriate security permissions to deploy the application

Ссылки на MSDN:

Статьи/Блоги:
Трассировка событий в приложении Windows Presentation Foundation
Поэтапное создание проекта установки и развертывания приложения WPF

MSDN Magazine/RU:
Поиск и устранение уязвимостей до выпуска приложения
Автоматизация тестирования пользовательского интерфейса в приложениях WPF

Video на TechDays/RU:
DependencyObject и DependencyProperty

Video на WindowsClient/EN:
Deploying a Standard WPF Application Using ClickOnce and Visual Studio
ClickOnce for Application Deployment

Подготовка к экзамену 70-511: TS: Windows Applications Development with Microsoft .NET Framework 4. Часть 4: Enhancing the Functionality and Usability of a Solution

>>В начало

Требования к знаниям:

  • Integrate WinForms and WPF within an application.
    This objective may include but is not limited to: using ElementHosts within WinForms and ControlHosts within WPF; using the PropertyMap property
  • Implement asynchronous processes and threading.
    This objective may include but is not limited to: implementing asynchronous programming patterns; marshalling between threads; freezing UI elements; using timers; Task Parallel Library; parallel LINQ; using the dispatcher; BackgroundWorker component
  • Incorporate globalization and localization features.
    This objective may include but is not limited to: loading resources by locale; marking localizable elements; using culture settings in validators and converters; using language properties and rendering direction properties; working with resource files for localization; determining installed locales; regional settings
  • Implement drag and drop operations within and across applications.
    This objective does not include: Dynamic Data Exchange (DDE)
  • Implement security features of an application.
    This objective may include but is not limited to: configuring Software Restriction Policy (SRP); full trust and partially trusted security; interoperability with legacy CAS policy; User Account Control (UAC)
  • Manage user and application settings.
    This objective may include but is not limited to: creating application settings; creating user settings; loading and saving settings
    This objective does not include: persisting to database
  • Implement dependency properties.
    This objective may include but is not limited to: enabling data binding and animation, property metadata, property change callbacks

Ссылки на MSDN:

Статьи/Блоги:
Доступ к значениям App.Config в WPF

MSDN Magazine/RU:
Создание более быстро реагирующих приложений с Dispatcher
Свойства зависимости и уведомления

Video на WindowsClient/EN:
How Do I: WinForms WPF Integration
How Do I: Use a WPF Control in a Windows Form using ElementHost
How Do I: Use Resource Files for Localization both in XAML and Code
How Do I: Build an Asynchronous Progress Bar in WPF
How Do I: Localize Applications using the CultureInfo Class

Подготовка к экзамену 70-511: TS: Windows Applications Development with Microsoft .NET Framework 4. Часть 3: Managing Data at the User Interface Layer

>>В начало

Требования к знаниям:

  • Implement data binding.
    This objective may include but is not limited to: binding options, static and dynamic resources, element bindings, setting the correct binding mode and update mode; binding to nullable values
    This objective does not include: binding to a specific data source
  • Implement value converters in WPF.
    This objective may include but is not limited to: implementing custom value converters, implementing multivalue converters
  • Implement data validation.
    This objective may include but is not limited to: handling validation and providing user feedback via the error provider (WinForms) or data templates (WPF), IDataErrorInfo, validation control, form validation and control validation
  • Implement and consume change notification interfaces.
    This objective may include but is not limited to: implementing INotifyPropertyChanged; using INotifyCollectionChanged (ObservableCollection)
  • Prepare collections of data for display.
    This objective may include but is not limited to: filtering, sorting, and grouping data; LINQ; CollectionView (WPF), BindingSource object (WinForms)
  • Bind to hierarchical data.
    This objective may include but is not limited to: TreeView; MenuControl
  • Implement data-bound controls.
    This objective may include but is not limited to: using the DataGridView (WinForms) or DataGrid (WPF) control to display and update the data contained in a data source, implementing complex data binding to integrate data from multiple sources; ItemsControl-derived controls (WPF)
  • Create a data template in WPF.
    This objective may include but is not limited to: implementing a data template selector; using templates with ItemsControl

Ссылки на MSDN:

Статьи/Блоги:
Интерфейс IValueConverter
Привязка данных к полю со списком WPF
DataGrid в WPF
Настраиваемый цвет сетки элемента управления Datagrid в WPF
Настраиваемая высота строки и заголовка элемента
управления Datagrid в WPF

Выравнивание ячеек в элементе управления DataGrid в WPF
Отображение иерархической структуры данных в WPF с помощью привязки и шаблонов
Шпаргалка по биндингу (PDF/EN)

MSDN Magazine/RU:
Настройка отображения данных с привязкой данных и WPF
Применение в WPF сложных бизнес-правил к вводу данных
Привязка данных в Windows Presentation Foundation
Класс ObservableCollection

 Video на TechDays/RU:
Создание приложений доступа к данным с помощью WPF
Лекция: Создание приложений доступа к данным с помощью Windows Presentation Foundation

Video на WindowsClient/EN:
How Do I: Use TargetNullValue to Handle Nullable Types in WPF Binding
How Do I: Use FallbackValue in WPF Binding
How Do I: Using StringFormat when Multibinding
How Do I: Change the Appearance of Grouped Data Using Styles
How Do I: Use CollectionViews to Sort and Filter Data
How Do I: Control Item Activation By Data Validation?
How Do I: Visually Indicate Binding Error Status
How Do I: Create a Custom Binding Validator
How Do I: Associate a Validation Rule with a Binding
Control How Data is Updated Using Binding Direction
Control When Bound Data is Updated
How Do I: Create and Use a Converter to Change DataTypes
How Do I: Build a ValueConverter to Format Bound Data in WPF
How Do I: Use the Observer Pattern

Подготовка к экзамену 70-511: TS: Windows Applications Development with Microsoft .NET Framework 4. Часть 2: Enhancing a User Interface by Using Advanced Techniques

>>В начало

Требования к знаниям:

  • Manage routed events in WPF.
    This objective may include but is not limited to: tunneling vs. bubbling events, handling and cancelling events
    This objective does not include: simple event handling; creating custom events
  • Configure WPF commanding.
    This objective may include but is not limited to: defining WPF commands based on RoutedCommand; associating commands to controls; handling commands; command bindings; input gestures
    This objective does not include: creating custom commands by implementing ICommand
  • Modify the visual interface at run time.
    This objective may include but is not limited to: adding/removing controls at run time; manipulating the visual tree; control life cycle; generating a template dynamically
    This objective does not include: instantiating forms and simple modification of control properties at runtime
  • Implement user-defined controls.
    This objective may include but is not limited to: deciding whether to use a user/composite, extended, or custom control ; creating a user/composite control; extending from an existing control
    This objective does not include: creating a custom control by inheriting directly from the Control class and writing code
  • Create and display graphics.
    This objective may include but is not limited to: creating and displaying graphics by using geometric transformation; brushes; drawing shapes; clipping; double buffering; overriding Render (WPF) and OnPaint (WinForms); differentiating between retained and non-retained graphics
    This objective does not include: creating and displaying three-dimensional graphics; hit testing; creating images
  • Add multimedia content to an application in WPF.
    This objective may include but is not limited to: media player vs. media element; adding a sound player; images
    This objective does not include: buffering
  • Create and apply control templates in WPF.
    This objective may include but is not limited to: template binding
    This objective does not include: styling and theming; data templating
  • Create data, event, and property triggers in WPF.

Ссылки на MSDN:

Статьи/Блоги:
Общие сведения о перенаправленных событиях и командах в WPF
Команды в WPF. Часть I
Команды в WPF. Часть II
Команды в WPF. Часть III
Вводное руководство по WPF - Часть IV (Шаблоны данных и триггеры)
Добавление проигрывателя Windows Media в приложение WPF

MSDN Magazine/RU:
Знакомство с маршрутизированными событиями и командами в WPF
Векторная графика и класс Shape WPF
Добавление видео к элементам управления и трехмерным поверхностям с помощью WPF
Точечные рисунки и биты пикселов

Video на TechDays/RU:
Использование стилей и шаблонов при создании пользовательского интерфейса
Лекция: Элементы управления в Windows Presentation Foundation
Лекция: 2D и 3D графика в Windows Presentation Foundation

Video на WindowsClient/EN:
How Do I: Create a Custom Command in WPF
How Do I: Use Command Binding in WPF
Create User Controls in WPF
Implementing Property Triggers in WPF
Implementing Data Triggers in WPF
Complex Logic Using Triggers in WPF
Interactivity Through Triggers in WPF Control Templates

Подготовка к экзамену 70-511: TS: Windows Applications Development with Microsoft .NET Framework 4. Часть 1: Building a User Interface by Using Basic Techniques

>>В начало

Требования к знаниям:

  • Choose the most appropriate control class.
    This objective may include but is not limited to: evaluating design requirements and then selecting the most appropriate control based on those requirements; recognizing when none of the standard controls meet requirements; item controls, menu controls, content controls
    This objective does not include: designing a custom control
  • Implement screen layout by using nested control hierarchies.
    This objective may include but is not limited to: using panel-derived controls, attaching properties
    This objective does not include: items controls, control customization
  • Create and apply styles and theming.
    This objective may include but is not limited to: application-level styles, overriding styles, style inheritance, Generic.xaml,  theming attributes
    This objective does not include: data-grid view style sharing
  • Manage reusable resources.
    This objective may include but is not limited to: fonts, styles, data sources, images, resource dictionaries, resource-only DLLs
  • Implement an animation in WPF.
    This objective may include but is not limited to: creating a storyboard; controlling timelines; controlling the behavior when the animation completes; double, color, and point animations; starting an animation from code and from XAML
    This objective does not include: direct rendering updates, implementing key frame animations

Ссылки на MSDN:

Статьи/Блоги:
Вводное руководство по WPF - Часть II (Layout)
Вводное руководство по WPF - Часть V (Стили)
Свойство зависимости в XAML
Работа с пропорциональными размерами в WPF
Стилизация приложений WPF
Windows Presentation Foundation : #013 Стилизация контролов WPF / Работа с ресурсами
Присоединенные свойства

 MSDN Magazine/RU:
Настройка элементов управления для Windows Presentation Foundation
Настройка элементов управления WPF при помощи шаблонов
Шаблоны для редко используемых элементов управления
Расширение классов анимации WPF

Video на TechDays/RU:
Лекция: Основы Windows Presentation Foundation
Основные принципы разработки приложений на WPF
Лекция: Шаблоны расположения элементов пользовательского интерфейса в Windows Presentation Foundation

Video на WindowsClient/EN:
WinForms-InheritingControls
How to Create a User Control in WPF
Windows Forms Layout
Layout Techniques for Windows Forms Developers
Grid Control Design-Time Row and Column Manipulation Features
Creating and Consuming Resource Dictionaries in WPF and Silverlight
How to Use Styles in WPF
How to Apply Control Templates in WPF
How to Use Data Templates in WPF
Sharing Styles Among Heterogeneous Elements
Override a Style for a Local Control’s Property Value in WPF
Style Inheritance using BasedOn in WPF
Apply Styles in WPF
Introduction to Themes in WPF
Basic Animation in WPF Using XAML
How Do I: Animate an Effect in WPF?
How Do I: Use Effects in WPF
Introduction to Easing Functions in WPF 4
How Do I: Custom Easing Functions in WPF 4

Подготовка к экзамену 70-511: TS: Windows Applications Development with Microsoft .NET Framework 4. Часть 0.

За выступление в MCP клубе обещали премировать еще одним ваучером на бесплатную сдачу экзамена. Поэтому решил закрыть ветку Windows Application Development. Начнем с 511 экзамена.

Вводные данные:
Основная страница экзамена.
Требования к знаниям.

 Building a User Interface by Using Basic Techniques (23%)

  • Choose the most appropriate control class.
  • Implement screen layout by using nested control hierarchies.
  • Create and apply styles and theming.
  • Manage reusable resources.
  • Implement an animation in WPF.

Enhancing a User Interface by Using Advanced Techniques (21%)

  • Manage routed events in WPF.
  • Configure WPF commanding.
  • Modify the visual interface at run time.
  • Implement user-defined controls.
  • Create and display graphics.
  • Add multimedia content to an application in WPF.
  • Create and apply control templates in WPF.
  • Create data, event, and property triggers in WPF.

Managing Data at the User Interface Layer (23%)

  • Implement data binding.
  • Implement value converters in WPF.
  • Implement data validation.
  • Implement and consume change notification interfaces.
  • Prepare collections of data for display.
  • Bind to hierarchical data.
  • Implement data-bound controls.
  • Create a data template in WPF.

Enhancing the Functionality and Usability of a Solution (17%)

  • Integrate WinForms and WPF within an application.
  • Implement asynchronous processes and threading.
  • Incorporate globalization and localization features.
  • Implement drag and drop operations within and across applications.
  • Implement security features of an application.
  • Manage user and application settings.
  • Implement dependency properties.

Stabilizing and Releasing a Solution (17%)

  • Implement a WPF test strategy.
  • Debug XAML by using the WPF Visualizer.
  • Debug WPF issues by using PresentationTraceSources.
  • Configure a ClickOnce deployment.
  • Create and configure a Windows Installer project.
  • Configure deployment security settings.

Основные ссылки:
Раздел по WPF MSDN
Портал Windows Forms на MSDN
Доклады по WPF на TechDays
Центр Windows Presentation Foundation на MSDN
WPF Tutorial (неплохой сайт с большим количеством примеров/EN)

Учебники/книги:
MCTS Self-Paced Training Kit (Exam 70-511): Windows Application Development with Microsoft .NET Framework 4
WPF: Windows Presentation Foundation в .NET 4.0 с примерами на C# 2010 для профессионалов