ColorPicker на WPF
25 января 2009 - 19:56
Нашел статейку (http://www.codeproject.com/KB/WPF/WPF_CustomerControl.aspx) про то как делать собственные контролы на WPF. Если не придираться к использованию терминов и формулировкам, то с приведенным способом написания своих контролов можно согласиться. А вот выбранный пример абсолютно неадекватен, т.к. ColorPicker в WPF можно сделать гораздо проще и быстрее с помощью DataTemplate.
Итак, для начала кинем на окно ListBox и сделаем так, чтобы ListBoxItems в листбоксе были расположены не по вертикали, а по горизонтали и переносились при достижении конца строки, для этого укажем, что вместо стандартной StackPanel в ListBox будет использоваться WrapPanel:
Теперь создадим DataTemplate для отображения цвета:
Осталась самая малость - задать список цветов и написать обработчик для выбора цвета. Список цветов можно задать двумя способами, в коде:
и в xaml-е:
А обработчик выбора цвета вешается на SelectionChanged листбокса, например такой:
Вот и все простой ColorPicker готов. Естественно все то, что я сейчас понаписал прямо в окне следует вынести в отдельный стиль и просто подключать его всякий раз, когда вам нужен выбор цветов.
Скачать исходники:
PS. А теперь об упомянутой в начале статье: в ней используется термин Custom Control, что неверно ибо в терминологии WPF это User Control - т.е. контрол с заданым внешним видом, тогда как Custom Control - это lookless контрол, т.е. не имеющий фиксированного внешнего вида, а использующий стили.
Итак, для начала кинем на окно ListBox и сделаем так, чтобы ListBoxItems в листбоксе были расположены не по вертикали, а по горизонтали и переносились при достижении конца строки, для этого укажем, что вместо стандартной StackPanel в ListBox будет использоваться WrapPanel:
<ListBox Name="colorsListBox" HorizontalAlignment="Center" Width="200" ItemTemplate="{StaticResource ColorTemplate}" SelectionChanged="OnNewColorSelected" SelectedIndex="1" Margin="0,0,0,21"> <ListBox.ItemsPanel> <ItemsPanelTemplate> <WrapPanel IsItemsHost="True" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}}"/> </ItemsPanelTemplate> </ListBox.ItemsPanel> </ListBox>
Теперь создадим DataTemplate для отображения цвета:
<DataTemplate x:Key="ColorTemplate"> <Grid Width="15" Height="15" Margin="0,2,2,2" ToolTip="{Binding}" Background="#00000000"> <Rectangle Margin="0,0,0,0" Stroke="Black"> <Rectangle.Fill> <SolidColorBrush Color="{Binding}"/> </Rectangle.Fill> </Rectangle> <Rectangle Margin="0,0,0,0" Stroke="#00000000"> <Rectangle.Fill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#00FFFFFF" Offset="0.692"/> <GradientStop Color="#BFFFFFFF" Offset="1"/> <GradientStop Color="#FFFFFFFF" Offset="0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> </Grid> </DataTemplate>
Осталась самая малость - задать список цветов и написать обработчик для выбора цвета. Список цветов можно задать двумя способами, в коде:
colorsListBox.ItemsSource = new Color[]{Colors.White,Colors.Blue,Colors.Red};
и в xaml-е:
<ListBox.ItemsSource> <x:Array Type="{x:Type Color}"> <Color A="255" R="255" G="255" B="255"/> <Color>Blue</Color> <Color>Red</Color> <Color>Black</Color> <Color>Cyan</Color> <Color>Magenta</Color> <Color>Orange</Color> <Color>Pink</Color> <Color>Yellow</Color> <Color>Gold</Color> <Color>Gray</Color> <Color>Green</Color> <Color>Indigo</Color> <Color>Khaki</Color> </x:Array> </ListBox.ItemsSource>
А обработчик выбора цвета вешается на SelectionChanged листбокса, например такой:
private void OnNewColorSelected(object sender, SelectionChangedEventArgs e) { (LayoutRoot.Background as GradientBrush).GradientStops[1].Color = (Color)colorsListBox.SelectedItem; }
Вот и все простой ColorPicker готов. Естественно все то, что я сейчас понаписал прямо в окне следует вынести в отдельный стиль и просто подключать его всякий раз, когда вам нужен выбор цветов.
Скачать исходники:
PS. А теперь об упомянутой в начале статье: в ней используется термин Custom Control, что неверно ибо в терминологии WPF это User Control - т.е. контрол с заданым внешним видом, тогда как Custom Control - это lookless контрол, т.е. не имеющий фиксированного внешнего вида, а использующий стили.