воскресенье, 20 марта 2011 г.

Показ разных кнопок в зависимости от наличия картинки

Название получилось какое то корявое, но я над ним еще подумаю. А задача весьма простая.
Итак, дано:
Есть класс, который является источником данных для кнопки. У класса есть два свойства: заголовок и картинка. Если картинка отсутствует, то показывается обычная кнопка с текстом. Если картинка задана, то показывается кнопка с картинкой, а заголовок становится tooltip-ом. Вроде все просто.
Итак начнем.
Для начала класс с которым мы будем ставить эксперименты:

class ButtonInfo : DependencyObject
 {
  /// 
  /// Заголовок
  /// 
  public string Title
  {
   get { return (string)GetValue(TitleProperty); }
   set { SetValue(TitleProperty, value); }
  }
 
  /// 
  /// Static part of dependency property Title
  /// 
  public static readonly DependencyProperty TitleProperty =
   DependencyProperty.Register("Title"typeof(string), typeof(ButtonInfo), new UIPropertyMetadata(""));
 
  
/// 
  /// Картинка
  /// 
  public string ImagePath
  {
   get { return (string)GetValue(ImagePathProperty); }
   set { SetValue(ImagePathProperty, value); }
  }
 
  /// 
  /// Static part of dependency property ImagePath
  /// 
  public static readonly DependencyProperty ImagePathProperty =
   DependencyProperty.Register("ImagePath"typeof(string), typeof(ButtonInfo), new UIPropertyMetadata(""));
}
Ну и собственно в DataContext кнопки мы будем помещать этот класс как то так:
ButtonInfo bi = new ButtonInfo() { Title = "Тестовая кнопка", ImagePath = "Image\\test.png" };
 button1.DataContext = bi
или

ButtonInfo bi2 = new ButtonInfo() { Title = "Тестовая кнопка без картинки" };
 button2.DataContext = bi2;
Все остальное будем делать через XAML.
Создадим для ControlTemplate для кнопки с рисунком:

 <ControlTemplate x:Key="ImageButton">
  <Button Width="30" Height="30" ToolTip="{Binding Title}">
   <Image Source="{Binding ImagePath}" />
  Button>
 ControlTemplate>
и кнопки без рисунка:
 <ControlTemplate x:Key="TextButton">
  <Button Width="180" Height="30" Content="{Binding Title}" />
 ControlTemplate>Ну и собственно стиль, который будет применять наши Template к кнопкам в зависимости от наличия пути к картинке:
 <Style x:Key="TemplateSelectorStyle">
  <Setter Property="Button.Template" Value="{StaticResource ImageButton}" />
  <Setter Property="Button.Tag" Value="{Binding ImagePath}" />
  <Style.Triggers>
   <Trigger Property="Button.Tag" Value="">
    <Setter Property="Button.Template" Value="{StaticResource TextButton}" />
   Trigger>
  Style.Triggers>
 Style>По этому стилю, буквально два комментария:
1. Мы связываем свойство Button.Tag с ImagePath в связи с тем, что Trigger может проверять только свойства класса Button
2. Ну а собственно в Trigger-е мы проверяя Tag, на самом деле проверяем свойство ImagePath объекта лежащего в DataContext.
Если на форме разместить кнопки и указать у них стиль:

Style="{StaticResource TemplateSelectorStyle}"
То, мы увидим в работающем приложении нечто такое:
Да, не забудьте убедиться, что по указанному пути действительно есть картинка.

Комментариев нет:

Отправить комментарий