Практическое руководства создания собственного элемента управления ComboBox (WPF)
Invite pending
В данной статье я хотел бы поделиться с вами примером создания очень распространенного элемента интерфейса — ComboBox используя технологию WPF. Суть статьи заключается в написание универсального компонента, способного быть применимым в любых проектах с минимальным изменением кода а также легко расширенным и стилизованным в дальнейшем по усмотрению автора. В данной статье я покажу подход, который для начинающих не является очевидным, а следовательно интересным.
Прежде всего, когда создается приложение с использованием WPF (и не только) технологии я считаю полезным применять практику использования компонентов, это делает код более структурированным и позволяет разбивать комплексную и объемную задачу на более мелкие и концентрироваться только на них.
Не всегда данные которыми оперирует компонент следует передавать в него по совершению какого-нибудь события, иногда удобно пользоваться только разметкой XAML и уходить от привычного C# кода. Рассмотрим именно этот вариант.
Поставим перед собой задачу использовать только XAML разметку для инициализации полей компонента ComboBox. Передать массив параметров в компонент можно только через массив, к счастью такая возможность у XAML имеется. Объявим массив полей в поле Resources
Уже пол дела сделано…
Базовая конструкция компонента приведена ниже и думаю в комментариях не нуждается
Осталось описать как класс компонента сможет принять этот массив и сформировать список с некоторым эффектом анимации перелистывания полей.
Исходный код проекта находится ниже, каждый может откомпилироваться и дополнить своим функционалом и заморочками…
Итоговый проект.
Прежде всего, когда создается приложение с использованием WPF (и не только) технологии я считаю полезным применять практику использования компонентов, это делает код более структурированным и позволяет разбивать комплексную и объемную задачу на более мелкие и концентрироваться только на них.
Не всегда данные которыми оперирует компонент следует передавать в него по совершению какого-нибудь события, иногда удобно пользоваться только разметкой XAML и уходить от привычного C# кода. Рассмотрим именно этот вариант.
Поставим перед собой задачу использовать только XAML разметку для инициализации полей компонента ComboBox. Передать массив параметров в компонент можно только через массив, к счастью такая возможность у XAML имеется. Объявим массив полей в поле Resources
<Window.Resources>
<x:Array Type="system:String" x:Key="daysOfWeek">
<system:String>Понедельник</system:String>
<system:String>Вторник</system:String>
<system:String>Среда</system:String>
<system:String>Четверг</system:String>
<system:String>Пятница</system:String>
</x:Array>
</Window.Resources>
<Grid Background="#15000000">
<my:iComboBoxComponent HorizontalAlignment="Left" Margin="276,199,0,0" x:Name="iComboBoxComponent2" VerticalAlignment="Top" itemStringArrayProperty="{StaticResource daysOfWeek}" />
</Grid>
Уже пол дела сделано…
Базовая конструкция компонента приведена ниже и думаю в комментариях не нуждается
<UserControl.Resources>
<Style x:Key="ContentLabelStyle" TargetType="{x:Type Label}">
<Setter Property="Height" Value="33" />
<Setter Property="FontSize" Value="14" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
</UserControl.Resources>
<Grid Name="mainGrid" Loaded="MainGrid_Loaded" Background="{x:Null}">
<ScrollBar Height="37" HorizontalAlignment="Left" Margin="152,0,0,0" Name="scrollBar1" VerticalAlignment="Top" Width="18" ValueChanged="itemsValueChanged" Maximum="3" SmallChange="1" />
<StackPanel Name="itemContainetr" HorizontalAlignment="Left" Width="150" Margin="1,1,0,-60">
<Label Content="Lorem Ipsum ..." Name="LoremIpsum" Style="{StaticResource ContentLabelStyle}" />
</StackPanel>
<Border BorderBrush="Silver" BorderThickness="1" Height="37" Name="border1" VerticalAlignment="Top" CornerRadius="0" HorizontalAlignment="Left" Width="152">
<Border.Background>
<LinearGradientBrush StartPoint="0, 0" EndPoint="0, 1">
<GradientStop Color="#FFD8D8D8" Offset="0.0" />
<GradientStop Color="Transparent" Offset="0.4" />
<GradientStop Color="Transparent" Offset="0.6" />
<GradientStop Color="#FFD8D8D8" Offset="1.0" />
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
Осталось описать как класс компонента сможет принять этот массив и сформировать список с некоторым эффектом анимации перелистывания полей.
private string[] itemStringArray;
public string[] itemStringArrayProperty
{
set
{
itemStringArray = new string[value.Length];
itemStringArray = value;
AddItemsIntoItemContainetr();
}
}
public void AddItemsIntoItemContainetr()
{
itemContainetr.Children.Clear();
for (int i = 0; i < itemStringArray.Length; i++)
{
Label label = new Label();
label.Content = itemStringArray[i];
label.Style = (Style)FindResource("ContentLabelStyle");
itemContainetr.Children.Add(label);
}
scrollBar1.Maximum = itemContainetr.Children.Count - 1;
itemContainetr.Margin = new Thickness(0, 0, 0, -LoremIpsum.Height * itemStringArray.Length);
}
Исходный код проекта находится ниже, каждый может откомпилироваться и дополнить своим функционалом и заморочками…
Итоговый проект.