Меню на WPF и Silverlight

Я давно хотел научиться делать выезжающие меню на WPF, и вот попалась задача, для которой это действительно необходимо. Для проекта я использовал VS 2010.

Идея в следующем: в верхней (боковой, нижней) части приложения есть меню. Ниже (выше, левее, правее) него находится контент. Меню уходит за край приложения и контент занимает его место. Казалось бы, все просто, но есть некоторые тонкости. Я нашёл два удобных способа.

Для начала рассмотрим способ, когда вёрстка рабочего пространства происходит с помощью Grid. Мы разбиваем её на 2 строки: верхняя для меню, нижняя для контента.

  1. <Grid x:name=»LayoutRoot»>
  2.  <Grid.RowDefinition>
  3.   <RowDefinition Height=»40″ />
  4.   <RowDefinition Height=»*» />
  5.  </Grid.RowDefinition>
  6. </Grid> 

* This source code was highlighted with Source Code Highlighter.

Теперь само меню. Я его сделал с помощью контейнера Border, который позволяет делать рамку и закруглённые углы.

  1. <Border Grid.Row=»0″ CornerRadius=»5″ x:Name=»Menu»>
  2.  <Border.Background>
  3.   <LinearGradientBrush EndPoint=»0.5,1″ StartPoint=»0.5,0″>
  4.    <GradientStop Color=»Black» Offset=»0″ />
  5.    <GradientStop Color=»LightGray» Offset=»1″ />
  6.   </LinearGradientBrush>
  7.  </Border.Background>
  8.  <Grid >
  9.   <Button HorizontalAlignment=»Right» Width=»81″ VerticalAlignment=»Top» Click=»Button_Click» Content=»Post» Height=»24″/>
  10.   <TextBox VerticalAlignment=»Top» Name=»TextUrl» Text=»input text» Margin=»0,0,87,0″/>
  11.   <TextBlock HorizontalAlignment=»Left» VerticalAlignment=»Top» Name=»Status» Text=»ready» Margin=»10,22,0,0″ Visibility=»Collapsed» />
  12.  </Grid >
  13. </Border> 
* This source code was highlighted with Source Code Highlighter.

В качестве контента можно использовать кнопку

  1. <Button Grid.Row=»1″ Content=»Button»/> 

* This source code was highlighted with Source Code Highlighter.

Теперь создаём анимации ухода и появления. Я это делал с помощь Expression Blend. Вот что получилось:

  1. <Window.Resources>
  2.  <Storyboard x:Name=»MenuHide»>
  3.   <DoubleAnimationUsingKeyFrames BeginTime=»00:00:00″ Storyboard.TargetName=»Menu» Storyboard.TargetProperty=»(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)»>
  4.    <EasingDoubleKeyFrame KeyTime=»00:00:00″ Value=»0″ />
  5.    <EasingDoubleKeyFrame KeyTime=»00:00:00.5000000″ Value=»-36″>
  6.     <EasingDoubleKeyFrame.EasingFunction>
  7.      <BounceEase EasingMode=»EaseOut» />
  8.     </EasingDoubleKeyFrame.EasingFunction>
  9.    </EasingDoubleKeyFrame>
  10.   </DoubleAnimationUsingKeyFrames>
  11.  </Storyboard>
  12.  <Storyboard x:Name=»MenuShow»>
  13.   <DoubleAnimationUsingKeyFrames BeginTime=»00:00:00″ Storyboard.TargetName=»Menu» Storyboard.TargetProperty=»(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)»>
  14.    <EasingDoubleKeyFrame KeyTime=»00:00:00″ Value=»-36″ />
  15.    <EasingDoubleKeyFrame KeyTime=»00:00:00.5000000″ Value=»0″>
  16.     <EasingDoubleKeyFrame.EasingFunction>
  17.      <BounceEase EasingMode=»EaseOut» />
  18.     </EasingDoubleKeyFrame.EasingFunction>
  19.    </EasingDoubleKeyFrame>
  20.   </DoubleAnimationUsingKeyFrames>
  21.  </Storyboard>
  22. </Window.Resources> 

* This source code was highlighted with Source Code Highlighter.

!! В случае Silverlight вместо <Windows.Resources> будес стоять </UserControl.Resources>

А в наше меню нужно добавить:

  1. <Border.RenderTransform>
  2. <TransformGroup>
  3.   <ScaleTransform/>
  4.   <SkewTransform/>
  5.   <RotateTransform/>
  6.   <TranslateTransform/>
  7. </TransformGroup>
  8. </Border.RenderTransform> 

* This source code was highlighted with Source Code Highlighter.

Теперь в наше меню можно добавить обработчики событий MouseEnter и MouseLeave. Код они будут содержать следующий 

  1. private void Menu_MouseEnter(object sender, MouseEventArgs e)
  2. {
  3.   MenuShow.Begin();
  4. }
  5. private void Menu_MouseLeave(object sender, MouseEventArgs e)
  6. {
  7.   MenuHide.Begin();
  8.  
* This source code was highlighted with Source Code Highlighter.

В случае WPF вам придется, кроме того, добавить два свойства и изменить конструктор следующим образом (для SilverLight не надо):

  1. Storyboard MenuHide;
  2. Storyboard MenuShow;
  3. public MainWindow()
  4. {
  5.   InitializeComponent();
  6.   MenuHide = (Storyboard)FindResource(«MenuHide»);
  7.   MenuShow = (Storyboard)FindResource(«MenuShow»);

* This source code was highlighted with Source Code Highlighter.

Теперь, запустив наш проект, мы видим красиво убирающееся меню. Тем не менее, наша копка на весь экран не растягивается. Что бы реализовать данное поведение, нужно уменьшить первую строку нашей сетки. Для начала в конструкторе окна добавим следующий код:

MenuHide.Completed += new EventHandler(MenuHide_Completed);

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

  1. void MenuHide_Completed(object sender, EventArgs e)
  2. {
  3.   LayoutRoot.RowDefinitions[0].Height = new GridLength(4);
* This source code was highlighted with Source Code Highlighter.

Теперь высота строки всего 4 пиксела. Это ровно столько, сколько от меню оставалось видно после анимации. И надо не забыть вернуть все на место, для этого в обработчик MouseEnter добавляем: 

  1. private void Menu_MouseEnter(object sender, MouseEventArgs e)
  2. {
  3.   MenuShow.Begin();
  4.   LayoutRoot.RowDefinitions[0].Height = new GridLength(40);
  5.  
* This source code was highlighted with Source Code Highlighter.

Если теперь мы запустим приложение, то после того как меню скрылось, контент расшириться, о меню мы больше не увидим. Дело в том, что оно мало того что уехало на 36 пикселов вверх. Меню вслед за строкой сетки, стало высотой в 4 пиксела. Соответственно оно полностью находится выше видимой зоны. Чтобы это исправить добавим несколько свойств нашему меню:

  1. <Border Grid.Row=»0″ CornerRadius=»5″ x:Name=»Menu» MouseEnter=»Menu_MouseEnter» MouseLeave=»Menu_MouseLeave» Height=»40″ Margin=»0,0,0,-40″ VerticalAlignment=»Top»> 

* This source code was highlighted with Source Code Highlighter.

После этих преобразований Меню будет вести себя так, как надо.

В следующий раз расскажу, как проделать подобное, если корневой контейнер StackPanel.

Реклама

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: