지금까지 UserControl만 주구장창 만들어보았으면
이번에는 Control을 만들어서 dll로 빼서 편리하게 사용해보자.
첨에는 프로젝트를 라이브러리 프로젝트로 하나 만든다.
그리고 일단 UI가 있는것은 스타일이 필요할테니 Theme 폴더안에 generic.xaml을 만들자
그리고 이렇게 입력하자
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:c="clr-namespace:AboutPageControlLibrary"
xmlns:sys="clr-namespace:System.Windows;assembly=System.Windows"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Style TargetType="c:AboutPageControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="c:AboutPageControl">
<Grid>
<ListBox x:Name="AppListBox" Margin="30,0,0,0" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
이렇게 해서 AboutPageControl을 만들고 그안에 단순히 ListBox만 하나 넣었다. x:name은 ApplistBox로 정했다.
자 이제
cs파일을 하나 만드는데 Control을 상속받자
public class AboutPageControl : Control
그리고 생성자를 만든다.
public AboutPageControl()
{
DefaultStyleKey = typeof(AboutPageControl);
이렇게 DefaultStylekey로 하여서 아까 generic.xaml에 정의된 스타일을 가져온다.
자 이렇게만 하고 프로젝트 하나 만들어서 여기 dll을 참조 한후 사용하면
ListBox가 보일것이다.(사실은 아무것도 안보일껏이다 itemSource가 없으니^^)
자 그럼 이제 Listbox에 ItemSource를 정의해보자.
일단 저기 generic.xaml에 정의한 스타일의 컨트롤을 호출을 해야 한다.
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this._listBoxControl = GetTemplateChild("AppListBox") as ListBox;
}
이렇게 OnApplyTemplate를 오버라이드 한후
GetTemplateChild를 이용해서 Listbox를 _ListBoxControl에 정의하였다. _listBoxControl은 전역변수에 이미 정의를 했다이로써 언제든지 ListBox를 쓸수 있게 되었다.
그후에 이제 이 Listbox Itemsource에 data를 넣어보자.
public AboutPageControl()
{
DefaultStyleKey = typeof(AboutPageControl);
this.Loaded += new RoutedEventHandler(AboutPageControl_Loaded);
}
loaded에 넣은 이유는 알것이다.
void AboutPageControl_Loaded(object sender, RoutedEventArgs e)
{
List<AppData> appDatas = new List<AppData>();
appDatas.Add(new AppData() { Id = "App1", Name = "himan2", Description = "haha" });
appDatas.Add(new AppData() { Id = "App1", Name = "himan2", Description = "haha" });
_listBoxControl.ItemsSource = appDatas;
_listBoxControl.ItemTemplate = ItemTemplate;
이렇게 itemsource를 넣었다.
그러면 이제 itemSource도 보일것이다. 근데 또 궁금증이 있다. itemTemplate은 어떻게 줄것인가?
Control이 아니라면 그냥 xaml상에서도 줄수 있지만 여기서 이렇게 behind로 해야만 했다.
저위에 정의 되어 있는 ItemTemplate은 이렇게 정의 해줘야 한다. 미리
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
public static readonly DependencyProperty ItemTemplateProperty =
DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(AboutPageControl), new PropertyMetadata(OnItemTemplateChanged));
protected static void OnItemTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
사실 OnItemTemplateChanged는 의미가 없는듯 ;;
이렇게 정의 해두고 generic.xaml 에
<Setter Property="ItemTemplate" >
<Setter.Value>
<DataTemplate>
<Grid x:Name="grid">
<Grid.Resources>
<c:FileNameToFilePathImageConverter x:Name="FTFConverter" />
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions >
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Image x:Name="image" Source="{Binding iconFileName, Converter={StaticResource FTFConverter}}" Grid.RowSpan="2" Width="99" Height="99"/>
<TextBlock x:Name="textBlock" Text="{Binding Name}" Grid.Column="1" FontWeight="Bold" Margin="20,0,0,0"/>
<TextBlock Text="{Binding Description}" Grid.Column="1" Grid.Row="1" FontSize="16" Margin="20,0,0,0" TextWrapping="Wrap" />
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
이렇게 Property에 이름을 ItemTemplate로 정의 한다면
ListBox에 ItemTemplate이 정의가 되어서 아주 멋있는 ListBox가 보여질것이다. 이미지와 글이 있는^^
이제 어떻게 컨트롤을 처음에 만들고 Listbox를 추가하며 그안에 itemSouce와 ItemTemplate을 정의 하는지 알려주었다