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

30 Ноя
2011

В данной статье я хотел бы поделиться с вами примером создания очень распространенного элемента интерфейса — 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);
}


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

Итоговый проект.
По материалам Хабрахабр.



загрузка...

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

Наверх