1

Тема: Обработчик XAML для Silverlight

Обработчик XAML для Silverlight

оригинал: XamlCruncher for Silverlight


Статический метод XamlReader.Load  реализованный в WPF и Silverlight – поразительно простой и мощный инструмент. Дайте ему текст разметки XAML и он выдаст объект. Очевидно, что метод XamlReader.Load предназначен для обработки XAML в приложениях во время их выполнения, но он также является и очень полезным инструментом для разработки.

Я слышал, что почти каждый программист Microsoft работавший над «Avalon» писал маленькую программу, использующую XamlReader.Load для того чтобы писать или редактировать XAML и сразу же видеть результат. Одна такая программа, включенная в официальный SDK называлась XAMLPad.

Я написал свой собственный инструмент на основе метода XamlReader.Load, названный XamlCruncher для своей книги «Приложение = Код + Разметка». В действительности вся эта книга построена на XamlCrucher’е. Добрая половина книги посвящена обучению построения клона текстового редактора Notepad, а вторая половина описывает создание XamlCruncher на основе уже созданного редактора.

Как и все настоящие WPF программисты пишу XAML вручную, и в этом деле XamlCruncher оказался очень полезным, даже если, в конечном счете, я перемещал XAML в проект Visual Studio.

С недавнего времени мне стал нужен похожий инструмент для Silverlight, и хотя я уверен, что кто-то до меня уже сделал нечто подобное, моя программа, которую я называю «XamlCruncher SL» возникла из желания увидеть, как некоторые возможности этой программы все еще могут быть полезны. Опробовать программу вы можете по пройдя по этой ссылке.

Thumbs up Thumbs down

2

Re: Обработчик XAML для Silverlight

XamlCruncher SL не имеет никаких наворотов. (По меньшей мере, сейчас; я возможно буду улучшать программу, если сочту это полезным.) По сути, вы пишите и редактируете XAML в левой стороне экрана, и видите результат справа. Эти две части отделены друг от друга сплиттером. Если XAML обрабатывается методом XamlReader.Load без ошибок, редактируемый текст отображается черным цветом, в противном случае текст становится красным, на на ошибку также указывает сообщение об исключении отображаемое в «строке состояния» внизу. Некоторые сообщения об ошибке указывают номер строки и столбец. Поэтому в правой части «строки состояния» отображается текущая строка и столбец каретки в редакторе.

Варианты «Сохранить» или «Загрузить» в XamlCruncher SL отсутствуют. (Очевидно, что возможность сохранения в изолированное хранилище будет первой в предполагаемом списке улучшений.) А пока, если вы хотите сохранить что-то из того, что напечатали в редакторе, выделите текст (Ctrl+A) и скопируйте его в буфер (Ctrl+C). Далее поступайте с ним как пожелаете. Точно также, если нужно поместить какой-то XAML в редактор, просто скопируйте и вставьте его туда (Ctrl+V).

В XamlCruncher SL так мало возможностей, что самой значительной можно назвать вот какую: когда вы нажимаете клавишу Tab находясь в редакторе, фокус не перепрыгивает на сплиттер, а вместо этого вставляются пробелы. (Звучит банально, но для этого мне пришлось перегрузить метод OnKeyDown.)

Thumbs up Thumbs down

3

Re: Обработчик XAML для Silverlight

Эта версия XamlCruncher SL не ставит обработчик исключения для события Application.UnhandledException. Если XAML без проблем загружается методом XamlReader.Load, но случается ошибка во время выполнения (что по моему опыту в WPF чаще всего случаетя в XAML-анимациях), программа не поймает ее. Для пример опопробуйте следующий фрагмент XAML в программе:

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <TextBlock Text="Hello, Silverlight!" 
               RenderTransformOrigin="0.5 0.5"
               HorizontalAlignment="Center"
               VerticalAlignment="Center"
               Foreground="Blue"
               FontSize="48"
               FontStyle="Italic"> 
        <TextBlock.RenderTransform> 
            <RotateTransform x:Name="rotate" /> 
        </TextBlock.RenderTransform> 
    </TextBlock> 
    <UserControl.Triggers> 
        <EventTrigger> 
            <BeginStoryboard> 
                <Storyboard> 
                    <DoubleAnimation 
                        Storyboard.TargetName="rotate"
                        Storyboard.TargetProperty="Angle"
                        From="0" To="360" Duration="0:0:3" 
                        RepeatBehavior="Forever" /> 
                </Storyboard> 
            </BeginStoryboard> 
        </EventTrigger> 
    </UserControl.Triggers>
</UserControl>

(Да, просто выделите, скопируйте и вставьте.) Если вы измените Storyboard.TargetName или Stroryboard.TargetProperty, XAML будет успешно распарсен, но случится ошибка во время выполнения, и в Internet Explorer можно будет увидеть значок с восклицательным знаком в нижнем левом углу с текстом «Error on page». Однако XamlCruncher SL продолжит работать, как если бы ничего не случилось, и если вы исправите ошибку, анимация возобновится. (Но предупреждающая иконка останется.) Я собираюсь разобраться с Application.UnhandledException, чтобы избежать подобного.

Thumbs up Thumbs down

4

Re: Обработчик XAML для Silverlight

Если вы впервые сталкиваетесь со счастьем интерактивного редактирования XAML, помните, что при распарсивании XAML методом XamlReader.Load имеются определенные ограничения. Корневой элемент не может содержать атрибут x:Class, и нельзя задать обработчики событий. К тому же я наткнулся на довольно странную вещь: любые нестандартные атрибуты начинающиеся с префикса «x» просто игнорируются. Для проверки вставьте следующий текст в любой элемент:

x:whatever="who knows?" 

И XamlReader.Load не будет иметь никаких возражений.

Теперь, когда у вас есть исходный код, вы можете спросить: «Могу ли я ссылаться на свою (или чью-либо еще) Sivlerlight DLL в XAML, который я пишу в XamlCruncher SL?» и ответом будет «Да, потому, что теперь у вас есть исходный код». Вот как это сделать:

Предположим вы скачали содержимое моей недавней записи блога Canonical Splines in WPF and Silverlight, скомпилировали решение, и теперь у вас есть DLL названная CanonicalSplineLib.dll, лежащая в каталоге CanonicalSplineLib\Bin\Debug.

В решении XamlCruncherSL в Visual Studio кликните правой кнопкой в проекте XamlCruncherSL по элементу References, выберите Add Reference, перейдите на вкладку Browse, найдите файл CanonicalSplineLib.dll и выберите его. Перекомпилируйте XamlCruncher SL. Теперь DLL будет включена в XAP файл, и вы можете ссылаться на нее также, как это делается в WPF: объявив пространство имен XML указывающее на пространство CRL и имя сборки. Вот версия XAML (немного модифицированная), которую я демонстрировал в предыдущем посте блога:

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:spline="clr-namespace:CanonicalSplineLib;assembly=CanonicalSplineLib">
    <UserControl.Resources>
        <Style x:Key="splineStyle"
               TargetType="spline:CanonicalSpline">
            <Setter Property="Points" 
                    Value="100 75 150 25 200 150 250 25 300 75" />
            <Setter Property="Stroke" Value="Blue" />
            <Setter Property="StrokeThickness" Value="5" />
        </Style>
    </UserControl.Resources>
    <StackPanel>
        <spline:CanonicalSpline Tension="0"
              Style="{StaticResource splineStyle}" />
        <spline:CanonicalSpline Tension="1"
              Style="{StaticResource splineStyle}" />
        <spline:CanonicalSpline Tensions="0 1 0 1 0" 
            Style="{StaticResource splineStyle}" />
    </StackPanel>
</UserControl>

Thumbs up Thumbs down

5

Re: Обработчик XAML для Silverlight

На самом же деле версия XamlCruncher SL, которую сделал доступной в онлайн режиме, включает в себя не только сборку CanonicalSpline, но также и все четыре DLL являющиеся частью Microsoft Silverlight Toolkit. (Исходный код содержит ссылки на эти сборки, которые вы можете изменить в соответствии с расположением DLL на своем локальном диске.) Это означает, что вы можете экспериментировать с такими вещами, как DockPanel:

<UserControl 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ctrls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
    FontSize="24">

    <ctrls:DockPanel>
        <TextBlock Text="Docked Top"
                   HorizontalAlignment="Center"
                   ctrls:DockPanel.Dock="Top" />
        <TextBlock Text="Docked Bottom"
                   HorizontalAlignment="Center" 
                   ctrls:DockPanel.Dock="Bottom" />
        <TextBlock Text="Docked Left"
                   VerticalAlignment="Center"
                   ctrls:DockPanel.Dock="Left" />
        <TextBlock Text="Docked Right"
                   VerticalAlignment="Center" 
                   ctrls:DockPanel.Dock="Right" />
        <TextBlock Text="Not docked at all!"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center" />
    </ctrls:DockPanel>
</UserControl>

Только убедитесь, что длинное объявление пространства XML скопировалось одной строкой и обратите внимание, что там указано Microsoft.Windows.Controls, а не System.Windows.Controls.

Thumbs up Thumbs down