Тултипы как в офисе 2007
19 августа 2009 - 21:30
В 2007-ом офисе появилось множество всяческих достаточно интересных элементов управления. В том числе достаточно привлекательная всплывающая подсказка (tooltip).
Сделать аналогичный tooltip в wpf возможно несколькими способами:Данный метод с точки зрения архитектуры wpf является самым правильным, но к сожалению для большого количества контролов задавать тултипы в xaml-е крайне утомительно, даже работая в Expression Blend.
Данный конвертер будет использоваться нами в стиле тултипа, чтобы получать его элементы. В данном примере я буду использовать такие элементы: <заголовок тултипа>|<описание тултипа>|<путь к изображению> , но при необходимости естественно не составит никаких проблем расширить количество элементов.
Теперь напишем DataTemplate, который будет использовать полученные из конвертера данные:
Ну и сделаем стиль визуально похожий на офис:
Вот и всё, задавая ToolTip="Button 1 Tooltip|Button 1 Tooltip Long Long Long Long Description|pack://application:,,,/;component/Ri.png" мы получим tooltip близкий, к тому, что реализован в офисе 2007.
Скачать исходники:
PS. Данный пример не претендует на какую-либо завершённость.
Сделать аналогичный tooltip в wpf возможно несколькими способами:
- Написать свой класс унаследованный от ToolTip-а, ввести в нём нужные свойства (заголовок, картинка и т.д.) , сделать нужный стиль и задавать его в xaml-е подобным образом:
<Control.ToolTip> <controls:MyToolTip Title="ToolTip Title" Description="ToolTip Description" ImageSource="pack://application:,,,/;component/Ri.png"/> </Control.ToolTip>
- Делаем тоже самое, что в предыдущем способе, только ещё пишем расширение разметки (markup extension) для того, чтобы упростить запись в xaml-е. Это позволяет нам сократить количество текста в xaml-е, но к сожалению в Expression Blend придётся все писать в коде, а не пользоваться интерфейсом пользователя.
- Написать конвертор, и использовать его, чтоб преобразовывать заданную в тултипе строку внутри стиля. Этот метод с точки зрения архитектуры wpf-а не является особо правильным, но зато получаем короткую запись в xaml-е и удобство пользования интерфейса Expression Blend-а. Ниже я распишу этот метод подробнее.
/// <summary> /// Конвертер - достаёт из тултипа строковой элемент по индексу /// </summary> [ValueConversion(typeof(string), typeof(string))] public class RibbonToolTipConverter : IValueConverter { ///<summary> ///Converts a value. ///</summary> ///<returns> ///A converted value. If the method returns null, the valid null value is used. ///</returns> ///<param name="value">The value produced by the binding source.</param> ///<param name="targetType">The type of the binding target property.</param> ///<param name="parameter">The converter parameter to use.</param> ///<param name="culture">The culture to use in the converter.</param> public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value == null) return string.Empty; string[] res = (value as string).Split('|'); int index = System.Convert.ToInt32(parameter); if (res.Length > index) return res[index]; return string.Empty; } ///<summary> ///Converts a value. ///</summary> ///<returns> ///A converted value. If the method returns null, the valid null value is used. ///</returns> ///<param name="value">The value that is produced by the binding target.</param> ///<param name="targetType">The type to convert to.</param> ///<param name="parameter">The converter parameter to use.</param> ///<param name="culture">The culture to use in the converter.</param> public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return null; } }
Данный конвертер будет использоваться нами в стиле тултипа, чтобы получать его элементы. В данном примере я буду использовать такие элементы: <заголовок тултипа>|<описание тултипа>|<путь к изображению> , но при необходимости естественно не составит никаких проблем расширить количество элементов.
Теперь напишем DataTemplate, который будет использовать полученные из конвертера данные:
<DataTemplate x:Key="ribbonToolTipDataTemplate"> <Grid HorizontalAlignment="Left" VerticalAlignment="Top"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock Text="" Margin="2" Grid.ColumnSpan="2" Grid.RowSpan="1" x:Name="fakeTextBlock" HorizontalAlignment="Left" Visibility="Hidden"/> <TextBlock Text="{Binding Converter={StaticResource RibbonToolTipConvert}, ConverterParameter=0}" Margin="2" FontWeight="Bold" TextWrapping="Wrap" Grid.ColumnSpan="2" Grid.RowSpan="1" x:Name="titleTextBlock" HorizontalAlignment="Left" Width="{Binding Path=Width, ElementName=fakeTextBlock}"/> <Image Source="{Binding Converter={StaticResource RibbonToolTipConvert}, ConverterParameter=2}" Margin="3,3,3,3" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="1" x:Name="image"/> <TextBlock Text="{Binding Converter={StaticResource RibbonToolTipConvert}, ConverterParameter=1}" TextWrapping="Wrap" HorizontalAlignment="Left" Margin="2,2,2,2" Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" x:Name="descriptionTextBlock" MaxWidth="300"/> </Grid> <DataTemplate.Triggers> <Trigger Property="Text" Value="" SourceName="descriptionTextBlock"> <Setter Property="Visibility" TargetName="image" Value="Collapsed"/> <Setter Property="Visibility" TargetName="descriptionTextBlock" Value="Collapsed"/> <Setter Property="FontWeight" TargetName="titleTextBlock" Value="Normal"/> <Setter Property="MaxWidth" TargetName="titleTextBlock" Value="300"/> </Trigger> </DataTemplate.Triggers> </DataTemplate>
<Style x:Key="{x:Type ToolTip}" TargetType="{x:Type ToolTip}"> <Setter Property="Placement" Value="Bottom"/> <Setter Property="VerticalOffset" Value="3"/> <Setter Property="Padding" Value="2"/> <Setter Property="ToolTipService.ShowDuration" Value="30000"/> <Setter Property="ContentTemplate" Value="{StaticResource ribbonToolTipDataTemplate}"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ToolTip}"> <Grid> <Border HorizontalAlignment="Stretch" Margin="2,2,0,0" Width="Auto" BorderThickness="0,0,2,2" BorderBrush="#2A000000" CornerRadius="2,2,2,2"/> <Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Height="Auto" Margin="0,0,2,2" BorderThickness="1,1,1,1" BorderBrush="#FF767676" CornerRadius="2,2,2,2"> <Border.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFFEFEFE" Offset="0"/> <GradientStop Color="#FFCADAEF" Offset="1"/> </LinearGradientBrush> </Border.Background> <ContentPresenter Width="Auto" Height="Auto" Margin="{TemplateBinding Padding}"/> </Border> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
Скачать исходники:
PS. Данный пример не претендует на какую-либо завершённость.