Surface2012. 4. 25. 11:46

보통 control을 만들때 genneric.xaml에 디자인을 구현하고 x:Name을 이용해서 해당 control의 cs안에서 컨트롤 하고 싶을때

이렇게 하면 된다.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using Microsoft.Surface.Presentation.Controls;

namespace MyControl
{
    [TemplatePart(Name = SurfaceInkCanvasName, Type = typeof(SurfaceInkCanvas))]
    public class DrawPanelControl : Control
    {
        //template
        internal const string SurfaceInkCanvasName = "xSurfaceInkCanvas";
        internal SurfaceInkCanvas SurfaceInkCanvasContainer;

        public DrawPanelControl()
        {
            DefaultStyleKey = typeof(DrawPanelControl);
        }

        public override void OnApplyTemplate()
        {
            SurfaceInkCanvasContainer = this.GetTemplateChild(SurfaceInkCanvasName) as SurfaceInkCanvas;

            SurfaceInkCanvasContainer.DefaultDrawingAttributes.Height = 10;
            SurfaceInkCanvasContainer.DefaultDrawingAttributes.Width = 10;
            SurfaceInkCanvasContainer.DefaultDrawingAttributes.Color = Colors.Red;

            base.OnApplyTemplate();
        }
    }
}

저렇게 TemplatePart를 class밖에서 잡고 OnApplyTemplate에서

SurfaceInkCanvasContainer = this.GetTemplateChild(SurfaceInkCanvasName) as SurfaceInkCanvas;

이렇게 정의 하면 된다.

generic.xaml에는 그냥 일반적으로 x:name을 썻다.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:controls="clr-namespace:MyControl"
                    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                    xmlns:Custom="http://schemas.microsoft.com/surface/2008"
                    xmlns:sf="clr-namespace:Microsoft.Surface.Presentation.Controls;assembly=Microsoft.Surface.Presentation"
                    mc:Ignorable="d">

    <Style TargetType="{x:Type controls:DrawPanelControl}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:DrawPanelControl}">
                    <Grid>
                        <sf:SurfaceInkCanvas x:Name="xSurfaceInkCanvas" Background="Bisque"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
Posted by 동동(이재동)
Windows Phone 72011. 3. 21. 18:36

지금까지 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을 정의 하는지 알려주었다

Posted by 동동(이재동)
Windows Phone 72011. 3. 21. 18:17

대부분 컨버터 쓸때

 

<phone:PhoneApplicationPage.Resources>
        <Converter:FileNameToFilePathImageConverter x:Key="FTFConverter" />        

 

이런식으로 phoneApplicationPage.Resources안에 넣는다.

 

그러면 Control을 만들려고 할때 쓰는 generic.xaml에서 쓸려면 어디에 넣어야 할까?

 

<Setter Property="ItemTemplate" >            
           <Setter.Value>                
               <DataTemplate>
                   <Grid x:Name="grid">
                       <Grid.Resources>
                           <c:FileNameToFilePathImageConverter x:Name="FTFConverter" />
                       </Grid.Resources>

 

그렇다 이런식으로 Grid.Resources같이  패널 안에 리소스를 만들어 쓰면 된다.

Posted by 동동(이재동)