Denis Gladkikh

outcoldman

My personal blog about software development

  • 01 Aug 2009
  • .NET, WPF, XAML, Expression Blend
  • 0 comments

В WPF мне понадобилось (захотелось) сделать контрол, который бы показывал процесс ожидания. Контрол я хотел сделать похожим на вращающийся круг, как в Vista cur. А так же мне захотелось попробовать это сделать в новом Expression Blend 3 (можно использовать 60 дневную пробную версию Expression Studio 3). Не обязательно использовать последнюю версию продукта - хватит и второй версии.

В какой-то мере, мой пост - это повторение вот этого материала (на английском), который я видел достаточно давно.

Контрол будем создавать в новом проекте. Для этого запустим Expression Blend и создадим новый проект WPF Application.

Make New WPF Application

После создания проекта у вас должно быть открыто первое главное окно приложения в редакторе, если нет, то нужно его открыть (приятно, что Blend создает окно с именем MainWindow, а не Window1 как Visual Studio). Выбираем инструмент Ellipse (первый рисунок внизу), и рисуем в окне два ровных круга, один внутри другого (правильные круги нам помогает рисовать зажатая клавиша Shift). Первый круг рисуем с диаметром 200, второй с диаметром 120. Не обязательно стараться, чтобы круги были четко один внутри другого - мы сделаем это позже достаточно просто.

Select Ellipse Tool Place Circles on Window

Следующим шагом мы создадим из этих двух кругов новый UserControl. Для этого выделяем оба круга и в контекстном меню (вызываем нажатием правой кнопки мыши) выбираем пункт Make Into UserControl.... В открывшемся окне обзываем новый контрол WaitControl и нажимаем OK. Теперь активным у нас будет окно редактирования контрола.

Make Into User Control... Make Into User Control

В окне редактирования контрола делаем отцентровку кругов посередине. Для этого выбираем оба круга и в контекстном меню объектов (вызываем правой кнопкой мыши) выбираем пункты Align->Horizontal Centers и Align->Vertical Centers. Дальше сделаем из двух кругов бублик, для этого, выделив оба круга, выбираем пункт меню из контекстного меню выбранных объектов Combine->Exlude Overlap - в результате у нас должен получиться бублик.

Align:Centers Combine:Exlude Overlap

Следующим действием мы должны разукрасить наш бублик. Тут каждый должен выбрать тон под ваше приложение, я привожу цвета, которые понравились лично мне. Итак, переходим на вкладку Properties (располагается справа), выбираем Brushes->Fill, ниже выбираем Gradient Brush (2 на нижнем первом рисунке), выставляем изначально цвет, с которого будет начинаться наш градиент для этого выбираем левый ползунок (3), и выбираем цвет из Editor при помощи перемещения курсора, либо можно вписать цвет в RGB, у меня это цвет #FF11171E, далее выбираем цвет на котором наш градиент будет заканчиваться (5) - у меня это #FFD0E6FF. Дальше поменяем цвет у контуров бублика, для этого выбираем Brushes->Stroke (1 на нижнем втором рисунке) и выставим тот же цвет, с которого у нас начинается градиент закраски (более темный) - #FF11171E.

Fill Color Stroke Color

Следующими действиями мы заставим наш бублик крутиться, для этого на вкладке Triggers (слева) добавляем новый Event (2 на рисунке), по умолчанию он будет происходить на событие Loaded - нам это и нужно. Добавляем теперь действия, которые будут происходить - создаем новый Storyboard (3). Blend спросит о создании нового Storyboard:"No Storyboard exists for you to begin or to control. One will ve created" - нажимаем OK. Идем на вкладку Objects and Timeline (слева внизу) и переводим время на 1 секунду (вторая картинка внизу) - именно за это время наш бублик будет совершать поворот на 360 градусов. Дальше мы должны запечатлеть кадр поворота для этого в окне редактирования контрола выбираем бублик и в уголке при наведении замечаем стрелочки, потащив за которые мы сможем покрутить наш бублик. Делаем оборот по часовой стрелке на 360 градусов, лучше крутить с зажатой клавишей Shift, так будут фиксироваться каждые 45 градусов.

Add Event  Time board Rotate

Теперь необходимо сделать, чтобы наш бублик вращался постоянно - для этого нужно выставить Repeat нашему действию. Для этого на вкладке Objects and Timeline выбираем в дереве объектов RenderTransform->Rotation->Angle и в контекстном меню выбираем Edit Repeat Count, в окне жмем на знак бесконечность и нажимаем OK.

Repeat Forever

Теперь сделаем наш контрол немного поменьше, для этого в редакторе изменим диаметр до 25 перетащив за уголки бублика. Вот, в принципе и все - наш контрол готов. Вы можете запустить проект (F5) и увидеть результат. Я после Blend'a я всегда подчищаю созданный им XAML. Для этого мы перейдем в режим редактирования XAML (1 на нижнем рисунке) и сделаем следующее: выставим DesignWidth и DesignHeight в 25 пикселей, уберем лишние Margin у объекта Path, так же можно более человечно назвать Key нашего Storyboard, например OnLoadedWaitingControl, главное не забыть поменять имя и в EventTrigger'e который его использует.

Untitled15

И на последок в свой контрол я добавил еще текст Processing..., для этого я, опять же, отредактировал полученный XAML: положил Grid внутрь DockPanel и добавил объект TextBlock (на картинке сверху видно, что в Blend 3 появился IntelliSense):

<DockPanel> 
  <Grid x:Name="LayoutRoot" DockPanel.Dock="Left" VerticalAlignment="Center"> 
    <Path ...> 
      ... 
    </Path> 
  </Grid> 
  <TextBlock Margin="5,0,0,0" VerticalAlignment="Center">Processing...</TextBlock> 
</DockPanel>

У Grid выставим DockPanel.Dock="Left", TextBlock сдвинем немного от бублика вправо при помощи Margin="5,0,0,0" и выставим у обоих контролов (Grid и TextBlock) VerticalAligment="Center". Результат:

Result

Исходный код данного примера можно скачать с MyDrive.

Comments