Silverlight без XAML

ОГЛАВЛЕНИЕ

Silverlight великолепен, позволяет многое делать с помощью шаблонов и пользовательских управляющих элементов. Но что если надо создать игру или просто классную демонстрацию со снегом для праздников?

•    Скачать исходники - 4.96 Кб

Зачем тогда нужен XAML? Следует избавиться от него.

Создание нового проекта Silverlight

Начните с создания нового проекта Silverlight привычным образом. Нажмите на Файл->Новый->Проект... в меню, или нажмите Ctrl+Shift+N.

Выберите приложение Silverlight из типов проекта Silverlight и дайте ему забавное имя, например, SilverlightWithoutXaml. И нажмите кнопку OK.

Можно создать динамический управляемый данными веб-проект ASP.NET MVC для размещения чудесной игры Silverlight, но для простоты статьи выбирается опция "Сгенерировать автоматически" из диалогового окна.

Удаление XAML

Теперь подождите секунду, чтобы дать Visual Studio создать файлы XAML, которые будут удалены через несколько мгновений... Visual Studio показывает проект, как на рисунке ниже. Сейчас просто удалите оба файла XAML. Файлы .cs удалятся автоматически.

Исключая некоторые конфигурации и сгенерированные файлы, теперь проект пустой. Поскольку Silverlight без кода не делает ничего, будет добавлен новый класс. Щелкните правой кнопкой мыши по проекту и перейдите к Добавить->Класс... Можно назвать его как угодно, к примеру, WithoutXamlApp.   

Silverlight  нужно место для запуска приложения. Следовательно, только что добавленный в решение класс должен порождаться от System.Windows.Application.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Collections.Generic;

namespace SilverlightWithoutXaml
{
    public class WithoutXamlApp : Application
    {
   
    }
}

Далее надо добавить файл HTML, вмещающий управляющий элемент Silverlight. Добавьте файл HTML таким же путем, как только что добавили класс. Щелкните правой кнопкой мыши по проекту и Добавить->Новый элемент... Выберите шаблон HTML-файла и назовите его StartPage.htm или как вам удобно. Добавьте следующее в тело файла HTML:

<object id="ID" type="application/x-silverlight-2" width="600" height="400">
    <param name="source" value="bin/debug/SilverlightWithoutXaml.xap" />
    <param name="background" value="#00000000" />
</object>

Конфигурирование проекта

Чтобы запустить приложение, надо внести несколько изменений в свойства проекта. Щелкните правой кнопкой мыши по проекту и перейдите в Свойства. Убедитесь, что объект запуска установлен в SilverlightWithoutXaml.WithoutXamlApp.

Перейдите на вкладку Отладка и нажмите кнопку со звездочками около радиокнопки Конкретная страница. Выберите StartPage.htm из диалогового окна и нажмите OK. Отлично! Нажмите F5, чтобы скомпоновать и запустить приложение, чтобы узнать, работает ли оно. Если выведется белая страница HTML в браузере с черным квадратом и загрузочной анимацией Silverlight в центре –  все хорошо. Если нет, снова прочитайте вышеприведенное.

Время для веселья. Теперь есть приложение Silverlight  без XAML! Что дальше? Вы видели снимок экрана в начале и думаете: "Эй! Я тоже хочу белые точки в приложении Silverlight!” Ниже они добавляются.

Прежде чем запустить цикл анимации и делать забавные вещи, придется дождаться, когда Silverlight завершит загрузку и запуск приложения. К счастью, когда это происходит, возбуждается событие. Сначала Silverlight запускает конструктор класса приложения. Это прекрасное место для регистрации в событии запуска. Добавьте следующий код в класс WithoutXamlApp:

public WithoutXamlApp()
{
    this.Startup += new StartupEventHandler(WithoutXamlApp_Startup);
}

void WithoutXamlApp_Startup(object sender, StartupEventArgs e)
{
}

Добавляется канва для рисования на ней. Этот холст присваивается this.RootVisual приложения. RootVisual является UIElement, содержащим основной пользовательский интерфейс для приложения, корень визуального дерева. Добавьте следующий код в метод WithoutXamlApp_Startup. Он инициализирует корень с помощью Canvas с черным фоном.

this.RootVisual = new Canvas()
{
    Background = new SolidColorBrush(Colors.Black)
};

Для цикла анимации будет использоваться DispatcherTimer. Он запускает поток при запуске и возбуждает событие с заданным интервалом. Этот таймер очень легко реализовать. Добавьте следующие четыре строки кода в метод WithoutXamlApp_Startup:

DispatcherTimer Timer = new DispatcherTimer();
Timer.Interval = new TimeSpan(300);
Timer.Tick += new EventHandler(Timer_Tick);
Timer.Start();

Выбранный интервал 300 дает плавную анимацию. Обработчик события для Timer.Tick показан ниже. Последняя строка сбрасывает время. С этого времени событие Tick вызывается каждые 0.03 секунды.

void Timer_Tick(object sender, EventArgs e)
{
}

Конец близок. Последний кусок кода состоит из трех частей. Первый проходит в цикле по всем точкам, обновляя их, и запоминает те, которые надо удалить из визуального дерева, второй производит фактическое удаление точек, а последний добавляет новую точку в случайную X-координату на Canvas. Взгляните:

void Timer_Tick(object sender, EventArgs e)
{
    // список точек, подлежащих удалению
    List<Ellipse> ElToRemove = new List<Ellipse>();
     foreach (Ellipse child in ((Canvas)this.RootVisual).Children)
    {
        // если точка покидает область холста
        if (Canvas.GetTop(child) > 400)
            ElToRemove.Add(child); // добавить ее в подлежащие удалению
        else
        {   //обновить координаты точек
            Canvas.SetTop(child, Canvas.GetTop(child) + 2);
            Canvas.SetLeft(child, Canvas.GetLeft(child) +
                                    (rnd.NextDouble() * 4) - 2);
        }
    }

    //удалить точки из визуального дерева
    foreach (Ellipse item in ElToRemove)
    {
        ((Canvas)this.RootVisual).Children.Remove(item);
    }

    //добавить новую точку в случайную координату x,
    //со случайным размером
    int size = rnd.Next(3, 15);
    Ellipse el = new Ellipse()
    {
        Width = size,
        Height = size,
        Stroke = new SolidColorBrush(Colors.White),
        StrokeThickness = size
    };
    Canvas.SetLeft(el, rnd.NextDouble() * 750 - 150);
    Canvas.SetTop(el, -15);
    //добавить точку в визуальное дерево
    ((Canvas)this.RootVisual).Children.Add(el);
}

Чтобы это заработало, надо объявить private Random rnd = new Random((int)DateTime.Now.Ticks); в начале класса. Это даст действительно случайные числа.

Теперь нажмите F5 и любуйтесь анимацией!

Что дальше?

Приведенное  выше служит отправной точкой для многих вещей. Можно использовать управляющий элемент Silverlight без XAML для изменения объектной модели документа HTML во время исполнения. Можно написать механизм отслеживания лучей, способный стать основой копии Wolfenstein 3D.