Pull to refresh

Практическое руководства создания собственного элемента управления ComboBox (WPF)

В данной статье я хотел бы поделиться с вами примером создания очень распространенного элемента интерфейса — ComboBox используя технологию WPF. Суть статьи заключается в написание универсального компонента, способного быть применимым в любых проектах с минимальным изменением кода а также легко расширенным и стилизованным в дальнейшем по усмотрению автора. В данной статье я покажу подход, который для начинающих не является очевидным, а следовательно интересным.

Прежде всего, когда создается приложение с использованием 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);
}


Исходный код проекта находится ниже, каждый может откомпилироваться и дополнить своим функционалом и заморочками…

Итоговый проект.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.