Surface2012. 5. 4. 12:00

Xaml이 아닌 코드로 만들어서 범용적이고 실용적으로 사용 가능

public static class FadeAnimationControl
{
    public static void Fade(UIElement target, double ValueFrom, double ValueTo, double Duration)
    {
        DoubleAnimation da = new DoubleAnimation();
        da.From = ValueFrom;
        da.To = ValueTo;
        da.Duration = TimeSpan.FromSeconds(Duration);
        da.AutoReverse = false;

        System.Windows.Media.Animation.Storyboard.SetTargetProperty(da, new PropertyPath("Opacity"));

        System.Windows.Media.Animation.Storyboard.SetTarget(da, target);

        System.Windows.Media.Animation.Storyboard sb = new System.Windows.Media.Animation.Storyboard();
        sb.Children.Add(da);

        EventHandler eh = null;
        eh = (s, args) =>
        {
            //target.Visibility = Visibility.Collapsed;
            sb.Stop();
            sb.Completed -= eh;
            target.Opacity = ValueTo;
        };
        sb.Completed += eh;

        sb.Begin();
    }
}

참고 : http://forums.create.msdn.com/forums/p/87462/525024.aspx

Posted by 동동(이재동)
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 동동(이재동)
Surface2012. 4. 25. 11:25

어휴 그냥 내가 컨트롤 프로젝트를 만들었을때 그냥 일반 c# 프로젝트를 만들어서 그런거 같다.

 

일단 많은 레퍼런스를 추가해야하고

 

꼭 AssemblyInfo.cs에

 

[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

 

이구문이 추가 되어야 한다.

이구문이 추가 되기위해서

사용한 네임스페이스는

using System.Resources;

using System.Windows;

이두개가 using되어야 한다.

이거때문에 완전 삽질함

 

참고 : http://charlass.wordpress.com/2012/02/17/wpf-onapplytemplate-is-not-getting-called/

Posted by 동동(이재동)
Windows Phone 72012. 3. 21. 16:59

텍스트블럭에 물흐르듯이 흘러가게 하는효과를 가진 컨트롤

자세한 내용은 샘플 참조




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 동동(이재동)