воскресенье, 10 октября 2010 г.

MVC. Razor vs NHaml

Когда первый раз читал про Razor View Engine в блоге Скота Гатри и наткнулся вот на такое описание цикла foreach:

clip_image002

Первое, что пришло в голову: «Так это же почти как NHaml!». В этой статье попытаюсь сравнить насколько эти два движка близки по удобству программирования. Для этого создам два пустых проекта с названиями RazorMVCApplication и NHamlMVCApplication (предполагается, что NHaml установлен и настроен).

Пусть модель будет предоставлять данные из базы ViewEngines, которая находится на Microsoft SQL Server 2008 Express. В этой базе будет только одна таблица с таким же названием и вот такой схемой:

clip_image004

В виде данных используем информацию о существующих движках для MVC Framework:

clip_image006

Сгенерируем модель по этой базе данных с помощью LinqToSQL для обоих наших проектов.

На следующем шаге создадим HomeController. У нас автоматически сгенерируется метод Index(). Создадим для него View (теперь все действия мы совершаем для Razor). Так как у нас нет master page, не забудем снять галочку с Select master pag). Если мы запустим наше приложение, то увидим пустую страницу. Именно она соответствует коду, автоматически сгенерированному в нашем View.

Теперь попробуем отобразить заголовок окна, заданный в контроллере. Для этого в методе Index() добавим следующую строку перед return View():

ViewData["Title"] = "Hello, Razor!";

* This source code was highlighted with Source Code Highlighter.

А также немного изменим секцию title в представлении:

<title>@View.Title</title>

* This source code was highlighted with Source Code Highlighter.

Это все, что нам нужно сделать для того, чтобы изменить заголовок из контроллера.

Давайте сделаем то же самое для проекта с NHaml:

Поскольку наше представление должно лежать во View/Home/Index, то создадим каталог Home и добавим в него пустой текстовый файл с именем Index.haml. Запустив приложение убедимся, что открывается чистая страница.

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

%html
  %head
    %title="My cool title"
  %body

В этом можно увидеть некоторое преимущество NHaml: нет необходимости писать закрывающие теги, все определяется отступами. На мой взгляд в этом кроется и основной недостаток – если представление большое, то бывает проблематично уследить за количеством отступов.

Получим значение заголовка, заданного в контроллере:

%html
  %head
    %title= ViewData.Title
  %body

 

Теперь вернемся к Razor и отобразим содержимое единственной таблицы базы данных.

В контроллере добавим:

using (var dc = new MVCApplicationDataContext())
{
  ViewData["ViewEngines"] = (from engine

in dc.ViewEngines select engine).ToList();
}

Во View:

<ul>
@foreach(var engine in @View.ViewEngines) {
           <li>@engine.Name</li>   }
</ul>

Повторим то же самое и для NHaml:

%body
    %ul
      -foreach (var engine in ViewData.ViewEngines)
        %li=engine.Name

Если в проекте есть куски представления, которые можно переиспользовать, то в Razor есть метод @Html.Partial(“PartialName”), который дает возможность вставить представление из другого файла. В NHaml для этого используются файлы с имененем, начинающимся с символа “_”. То есть, если мы хотим вставить представление из файла с именем _partialname, то напишем так:

%body
    _partialname
    %ul
      -foreach (var engine in ViewData.ViewEngines)
        %li=engine.Name

Большинство языковых конструкций очень похожи, и принцип их использования одинаков. Но тогда встает вопрос об удобствах, предоставляемых Visual Studio, ведь именно они буду определять решающую роль в скорости разработки. И тут в случае NHaml мы натыкаемся на такую ситуацию: intellisense в виде плагина есть только для VisualStudio 2008, когда будет для 2010 никто не знает. Есть утилита позволяющая подсвечивать код, но это помогает незначительно. Для Razor intellisense появится, скорее всего, вместе с релизом MVC 3.

пятница, 8 октября 2010 г.

Windows Phone 7. Работа с камерой

В этой статье расскажу о том, как можно получать изображения с камеры в Windows Phone 7. Нужно понимать, что невозможно получить доступ к камере напрямую. Можно только воспользоваться стандартной утилитой, которая позволяет сделать фотографию и передать ее обратно в приложение. Такое поведение утилит в Windows Phone 7 носит название задач выбора (choosers). Помимо этого есть задачи выполнения (launchers), которые ведут себя так же, как и задачи выбора, но не передают никаких данных обратно в приложение. Благодаря им можно из вашего приложения вызывать адресную книгу, прерывать ваше приложение телефонным вызовом и т.д. Обо всем этом подробнее поговорим в следующих статьях.

Давайте попробуем получить изображение с камеры. Для этого создадим новый проект Windows Phone Application, назовем его, например, WindowsPhoneCameraApplication. Изменим заголовки и добавим элемент Image с именем cameraImage на страницу:

clip_image002

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

Для работы с камерой нам понадобится пространство имен Microsoft.Phone.Tasks, в котором содержится chooser CameraCaptureTask.

Напишем такой код:

    public partial class MainPage : PhoneApplicationPage
    {
        CameraCaptureTask camera;

        public MainPage()
        {
            InitializeComponent();

            camera = new CameraCaptureTask();
            camera.Completed += SendToCameraImage;
            camera.Show();
        }

        void SendToCameraImage(object sender, PhotoResult agrs)
        {
            if (agrs.TaskResult == TaskResult.OK)
            {
                var bmp = new BitmapImage();
                bmp.SetSource(agrs.ChosenPhoto);
                cameraImage.Source = bmp;
            }
        }
    }


Мы используем обработчик SendToCameraImage по событию завершения работы камеры для того, чтобы сохранить полученный снимок в формате bmp из потока, содержащегося в ChosenPhoto. Метод Show просто инициализирует chooser по работе с камерой.

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

Попробуем запустить без отладки, нажав Ctrl+F5:

clip_image004

Важным является то, что при запуске приложения по работе с камерой наше приложение переходит в состояние захоронения. То есть сохраняется состояние программы, для того, чтобы запустить ее после получения снимка с камеры. Именно по этой причине во время запуска с отладчиком при запуске  утилиты по работе с камерой Visual Studio рапортует о завершении приложения и возвращается в режим редактирования. Как можно продолжить отладку после завершения работы с камерой? Сделав снимок и нажав кнопку «Accept», нужно в течение 10 секунд нажать на кнопку F5, и Visual Studio снова подключится к приложению.

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