'분류 전체보기'에 해당되는 글 653건

  1. 2012.04.26 [surface] 해당 UserControl만 스크린샷(캡쳐) 하기
  2. 2012.04.25 [surface] Media.Brush를 Media.Color로 Convert 하는 법
  3. 2012.04.25 [surface] generic.xaml의 x:Name을 잡아내서 Control안에서 조정하기
  4. 2012.04.25 [surface] Control만들때 OnApplyTemplate()이 호출되지 않을때
  5. 2012.04.05 [wp7] ViewModel에서 View로 바로 접근하기
  6. 2012.03.22 [wp7] 별점 컨트롤 (Rating Control)
  7. 2012.03.22 [wp7] 강제로 소수점 표현하기
  8. 2012.03.21 [wp7] MarqueeTextBlock Control
  9. 2012.03.14 [wp7] SplashImage(BackgroundImage) 화질을 좋게 해보자 (그라데이션 계단현상 제거)
  10. 2012.03.13 [wp7] ListBox에서 해당 Item의 Cell만 DataTemplate 바꾸기
  11. 2012.03.08 [wp7] 리스트 컨트롤에서 Cell 순서를 아이폰처럼 바꾸어 보자. List ReOrder
  12. 2012.03.06 [wp7] 공용으로 쓰는 Converter는 App.xaml에 보관하자.
  13. 2012.02.23 [Potfolio] Window Phone 7 App 코레일 공식 앱 "글로리" (Hugeflow 2011.12~ 2012.2) 1
  14. 2012.02.23 [wp7] ConverterParameter 사용하기
  15. 2012.02.21 [wp7] 초성 검색 만들기 2
  16. 2012.02.16 [wp7] MessageBox를 띄운 상태에서 Tombstone
  17. 2012.02.15 [wp7] Group Listbox 만들기
  18. 2012.02.08 [wp7] Textbox간의 AutoFoucs 를 쉽게 등록 하자
  19. 2012.02.08 [wp7] URLDiffer 프로그램
  20. 2012.02.03 [wp7] 윈폰7에선 TextboxChanged 이벤트가 2번 들어온다?
  21. 2012.02.03 [wp7] PasswordBox 에 대한 고찰…(PasswordBox에서 Inputscope)
  22. 2012.01.30 [wp7] List의 선택한 값의 Index값을 알고 싶을때 IndexWhere
  23. 2012.01.30 [wp7] Linq에서 StackPanel 의 Children에 있는 Item 비교하기 (Casting)
  24. 2012.01.26 [wp7] Navigate 페이지간 이동시 데이터 전송하는 여러가지 방법
  25. 2012.01.19 [wp7] Model Class의 Properties 를 얻어와서 소스 최적화 및 코드를 줄여보자.
  26. 2012.01.18 [wp7] ListBox 바인딩 했을 때 안에 CheckBox 체크
  27. 2012.01.09 [wp7] Isolatedstorage와 블랜드 충돌 해결법 (unable to determine application identity of the caller)
  28. 2012.01.03 [wp7] UserControl 안의 Property를 부모의 컨트롤에 바인딩하기
  29. 2012.01.03 [wp7] UserControl을 ViewModel처럼 Property Binding
  30. 2011.12.28 [wp7] ListBox 선택했을때 Style 바꾸기
Surface2012. 4. 26. 10:08
private void Snapshot(UIElement source, double scale, int quality)
       {
           double actualHeight = source.RenderSize.Height;
           double actualWidth = source.RenderSize.Width;

           double renderHeight = actualHeight * scale;
           double renderWidth = actualWidth * scale;

           RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)renderWidth, (int)renderHeight, 96, 96, PixelFormats.Pbgra32);
           VisualBrush sourceBrush = new VisualBrush(source);

           DrawingVisual drawingVisual = new DrawingVisual();
           DrawingContext drawingContext = drawingVisual.RenderOpen();

           using (drawingContext)
           {
               //drawingContext.PushTransform(new ScaleTransform(scale, scale));
               drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
           }
           renderTarget.Render(drawingVisual);

           JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
           jpgEncoder.QualityLevel = quality;
           jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));

           using (FileStream stm = File.OpenWrite(@"C:\test2.png"))
               jpgEncoder.Save(stm);
       }

일단 소스는 이렇다 source에 해당 usercontrol을 넣는다.

만약 DrawingVisual에 넣어서 rectangle을 만들지 않으면 해당 유저컨트롤만 찍히는게 아니라 전체가 찍힌다.

전체가 찍히긴하지만 해당 컨트롤만 나옴

참고 :

http://www.grumpydev.com/2009/01/03/taking-wpf-screenshots/
Posted by 동동(이재동)
Surface2012. 4. 25. 14:41

반대로 Media.Color를 Brush로 바꾸는건 쉬웠지만

 

Brush를 Color로 바꾸는건 힘들었다.

 

var temp = ((e.Source as ListBox).SelectedItem as Brush);
         SolidColorBrush c = new BrushConverter().ConvertFromString(temp.ToString()) as SolidColorBrush;

         SurfaceInkCanvasContainer.DefaultDrawingAttributes.Color = c.Color;

내가 사용한 방법이다. brush를 SolidColorBrush로 BrushConvert의 도움을 받아서 컨버팅한후 Color프로퍼티를 이용하였다.

참고 : http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/fb164db0-c169-4d0e-85dc-c79163ea3aac/

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. 4. 5. 17:51

계속 SelectIndex가 바꼈는데도 SelectChanged이벤트를 일으키지 않아서

ViewModel에서 이렇게 바로 View로 접근해서 수정하였다.

 

Deployment.Current.Dispatcher.BeginInvoke(delegate
                {
                    ((Application.Current.RootVisual as Microsoft.Phone.Controls.PhoneApplicationFrame).Content as GloryApp.Views.CheckInListView).xTicketList.SelectedIndex = -1;
                    ((Application.Current.RootVisual as Microsoft.Phone.Controls.PhoneApplicationFrame).Content as GloryApp.Views.CheckInListView).xTicketList.SelectedIndex = 0;
                });
Posted by 동동(이재동)
Windows Phone 72012. 3. 22. 16:10

실버라이트 툴킷에는 있는데 윈폰 툴킷에는 업어서

내가 만들려는 찰나 찾았따 ㅋ

 

참고 : http://wp7wonders.wordpress.com/2010/10/15/use-the-rating-control-in-windows-phone-7/

Posted by 동동(이재동)
Windows Phone 72012. 3. 22. 15:15

예전 포스팅에도 썻던건데

 

소수점 표현을 하기 위해서 stringformat을 사용한다.

강제로 2자리까지 소수점을 표현하고 싶다면

<Run Text="{Binding Number, StringFormat=\{0:n2\}, ElementName=userControl}"/>

이런식으로 사용한다.

 

참고 :  http://www.kunal-chowdhury.com/2011/05/formatting-text-in-silverlight-xaml.html

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

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

자세한 내용은 샘플 참조




Posted by 동동(이재동)
Windows Phone 72012. 3. 14. 15:32

WMAppManifest.xml

에서

 

<App xmlns="" ProductID="{fdc14f57-6675-4eac-a1ce-fdd2c0133dd5}" Title="MnetWP7" RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal" Author="MnetWP7 author" Description="Sample description" Publisher="MnetWP7" BitsPerPixel="32">

저부분에

BitsPerPixel="32"

이걸 추가하면 된다.

 

끝~

너무 쉽다 ㅋ

Posted by 동동(이재동)
Windows Phone 72012. 3. 13. 20:03

예전에 DataTemplateSelector라는거에 대해서 포스트 했었다.

그건 보여주는것에 대해서 DataTemplate을 유동적으로 바꾸는것이였다.

하지만 이번에 할것은 어떤 특정한 이벤트 예를 들어 ListBox의 Item에 버튼을 클릭하면 해당셀의 TextBlock이 수정할수 있는

TextBox로 변하게 한다등등 셀의 DateTemplate을 마음대로 변경할수 있다.

일단 listbox를 만든다. 하지만 난 여기서 ReorderListbox를 이용했음으로 reorderlistbox로 설명하겠다.

 <ct:ReorderListBox x:Name="listBox" Grid.Row="1" ItemsSource="{Binding Data}" Foreground="{StaticResource PhoneForegroundBrush}" IsReorderEnabled="True" ItemTemplate="{StaticResource MyAlbumDataTemplate}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:Interaction.Behaviors>
                        <ec:ConditionBehavior>
                            <ec:ConditionalExpression>
                                <ec:ComparisonCondition LeftOperand="{Binding SelectedIndex, ElementName=listBox}" Operator="NotEqual" RightOperand="-1"/>
                            </ec:ConditionalExpression>
                        </ec:ConditionBehavior>
                    </i:Interaction.Behaviors>
                    <i:InvokeCommandAction Command="{Binding SelectAlbumCommand}" CommandParameter="{Binding SelectedItem, ElementName=listBox}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </ct:ReorderListBox>

아래 selectChanged 이벤트는 무시해도 된다. 하지만 대부분 behind에서 하는 이벤트 처리를 xaml에서 하게 할수 있다(보너스)

 

그리고 리소스를 등록한다.

 

 <UserControl.Resources>
        <DataTemplate x:Key="TextBoxDataTemplate">
                <Grid d:DesignWidth="385" d:DesignHeight="100" Height="80" Margin="0,0,0,10">
                    <Button Content="R" x:Name="RenameButton" Click="RenameButton_Click" Grid.Column="1" >
                        <tk:ContextMenuService.ContextMenu>
                            <tk:ContextMenu>
                                <tk:MenuItem Header="변경" Click="RenameButton_Click"/>
                            </tk:ContextMenu>
                        </tk:ContextMenuService.ContextMenu>
                    </Button>

머 이렇식으로 시작해서 만들자 각각 다른것을 2개를 만들어야 한다. 한개는 일반꺼 한개는 클릭했을때 나오는 dataTempalate

 

자이제 DateTemplate 안에 클릭했을때 itemTemplate을 변경해보자

private void RenameButton_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            (listBox.ItemContainerGenerator.ContainerFromItem((sender as Button).DataContext as MyAlbum) as ReorderListBoxItem).ContentTemplate = this.Resources["TextBoxDataTemplate"] as DataTemplate;
            //(listBox.ItemContainerGenerator.ContainerFromIndex(0) as ListBoxItem).ContentTemplate = this.Resources["TextBoxDataTemplate"] as DataTemplate;
        }

 

아래는 index로도 바꿀수 있다는 예시를 했다. 이렇게 하면 해당셀의 ContentTemplate을 얻어올수 있고 직접 넣을수 있다.

 

참고 : http://stackoverflow.com/questions/329556/focus-on-a-textbox-in-a-datatemplate

Posted by 동동(이재동)
Windows Phone 72012. 3. 8. 16:27

현재 Mnet을 작업하는데 Mnet에서 PlayList를 순서를 마음대로 바꿀수 있게 바꿔야 했다.

아이폰에서나 가능한 순서 바꾸기… 아무리 찾아봐도 순정 Listbox에는 할수 없다.

아이폰이나 안드로이드는 기본컨트롤에서 바꿀수 있는데 왜 윈폰은 없냐고!!!

하지만 누군가 만들어 놓은게 있어서 고맙게 이용해서 성공했다.

 

 

수정모드를 설정할수 있으며

수정모드에서 삭제버튼등을 추가할려면 아쉽게도 DataTemplate을 바꾼후 다시 리로딩해서 수정모드로 가야 한다.

바꾸는 방법은 포스팅했으니 참고 바란다.

자세한 사항은 소스를 참고하자

내가 참고한곳 : http://blogs.msdn.com/b/jasongin/archive/2011/01/03/wp7-reorderlistbox-improvements-rearrange-animations-and-more.aspx

내가 새로 만든 테스트 소스

Posted by 동동(이재동)
Windows Phone 72012. 3. 6. 16:30

<Application.Resources>

        <ResourceDictionary>

에 들어가면 된다.

 

<Converters:MusicVideoExistVisiblityConverter x:Key="MusicVideoExistVisiblityConverter" />

이런 컨버터를 모든 View에 다 넣을려고 하면 힘드니깐..

 

app.xaml에 보관하면 다음부터 쓸때 그냥 컨버터 이름만 쓰면 된다.

Posted by 동동(이재동)
포트폴리오2012. 2. 23. 15:20

정말 힘들었던 프로젝트중 하나입니다. 일단 개발자는 1명(저!!!) 디자이너 1명(기백)

이렇게 시작했던 프로젝트였고 역시 끝날때도 이렇게 추가 없이 끝났습니다.

일단 짧은 기간, 방대한 양의 업무파악,아이폰과 100% 똑같아야 한다는 부담감, 기획서도 없습니다.

일단 엄청나게 좋지 않은 조건에서 시작하였고

기획서가 없어서 아이폰소스를 보면서 하나하나 참고해야했고(아이폰 앱을 만들어 보지 않았다면 못했을 작업)

어떤 기능이 있는지 몰라서 하나하나 실행하면서 했었습니다. 물론 정말 꼼꼼하게 봤었고 모르는게 있으면 메신저로 코레일 직업원에게 물어봤었는데 웬만하면 아이폰소스랑 제 핸드폰을 이용해서 기능을 배웠습니다.

직통, 환승 에 따라 UI가 다 다르고, 할인은 또 얼마나 종류가 많은지 ㅠㅠ (아니 열차안에서 언제부터 영화를 볼수 있고 좌석을 선택할수 있었던거지??? 영화 예매까지도 구현해야되?)

그리고 알수 없는 수많은 API들... , 윈폰에는 없는 아이폰 전용 컨트롤들...

프로젝트 마지막에 아이폰말고 안드로이드 테스트해서  왜 다르냐고 어이 없는 상황까지...

그리고 아이폰 1년동안 업그레이드 한것들을 그대로 적용해야했기때문에 시간도 모잘랐고

아이폰은 8명인가? 개발하고 개발 시간도 많았던데 난 왜 혼자서 2달만에 개발하라는건지 모르겠네요. 덕분에 맨날 야근

스트레스도 많이 받았지만 무사히 코레일 공식앱을 완성해서 기쁩니다. 

남은게 있다면 코레일 취직해도 될만큼 철도 전문가가 되었네요 하하하 늘어야할 코딩실력은 안늘고...ㅠㅠ


 

 

 

 

 

 

 

 

 

 

 

 

 

 

Posted by 동동(이재동)
Windows Phone 72012. 2. 23. 10:31

ConverterParameter를 사용하면 Converter를 만드는일을 줄일수 있다.

만약 20120223 이라는 Date를

각각 텍스트블럭에 2012년 02월 23일 처럼 넣고 싶은데 한번에 넣을수도 있지만 년월일이 색상이나 크기가 다를때는

택스트 블럭을 각각 만들어 넣어야 한다.

그렇다면 이것을 각각 YearConverter,MonthConverter,DayConverter 이렇게 3개의 컨버터를 만들어서 해야 하는가?

물론 가능하지만 엄청 귀찮은 일이 될것이다.

그럴때 paramter를 쓰면 편하다.

object형이라서 아무거나 넣을수 있지만 string같은경우는 “” 이렇게 따옴표로 묶을수 있는데 따옴표는 쓰면 안된다.

꼭 ‘’ 로 묶자

<TextBlock TextWrapping="Wrap" Text="{Binding h_dpt_dt, Converter={StaticResource YearConverter},ConverterParameter='Year'}" Foreground="Black" HorizontalAlignment="Left" Margin="10,0,0,0" FontWeight="Bold" VerticalAlignment="Bottom"/>

 

이렇게 사용하면 된다.

 

Converter에서는

public class DateCropConverter :IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null)
                return string.Empty;

            if (parameter.Equals("Year"))
            {
                return (value as string).Substring(0, 4);
            }
            else if (parameter.Equals("Month"))
            {
                return (value as string).Substring(4, 2);
            }
            else
            {
                return (value as string).Substring(6, 2);
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

이렇게 parameter로 넘어오기때문에 컨버터를 굳이 3개 를 만들필요 없이 하나로 해결하였다.

Posted by 동동(이재동)
Windows Phone 72012. 2. 21. 15:26

윈폰에서는 초성검색을 기본적으로 지원하지 않는다. ㅠㅠ

그래서 할 수없이 만들어야 한다.

일단 초성 검색의 원리는 이렇다.

TextBox에 쓰여진글이 서울 이라면

일단 글자들을 하나하나씩 추출해내고 ‘서’,’울’  이렇게 이 글자들을 또 다시 초성,중성,종성으로 나눈다.

‘ㅅ’,’ㅓ’ 이런식으로

그러면 서울을 추출해냈으니 ‘ㅅ’,’ㅇ’ 이라는 2개의 char형 자료가 생긴다.

이것을 Itemsource Model에 저장한다.

그래서 텍스트박스에 입력된 첫글자가 ㅅ 이라면 저장해놓은 ㅅ ㅇ의 첫글자를 검색해서 보여주면 되는것이다.

두번째 글자가 ㅇ 이라면 이것도 역시 두번째 값을 검색해서 ㅇ 이라는 글자가 있는것을 보여준다.

단 두번째에서는 검색시 첫번째 검색결과에서 두번째값을 검색한다!

그리고 만약 초성 검색이 아닌 그냥 일반 서울로 검색할경우는 이것이 한글인지 아닌지를 판별하는 코드가 있는데 이것을 사용한다.

이코드는 한글을 초성,중성,종성으로 분리해 주는 class이다.

자세한 설명은 내가 샘플로 구현을 해 놓았다.


 

Posted by 동동(이재동)
Windows Phone 72012. 2. 16. 17:12

코레일 만드는도중 앱이 꺼졌다 이유를 보니

MessageBox가 띄워져 있는 상태에서  ok를 누르면 프로세서를 타고

cancel을 누르면 navivation.goback()을 하게 되어 잇는데

메세지 박스가 띄워져 있는 상태에서 tombtone을 하게 되면

cancel 된 분기문으로 가게 되어 있는데

거기에서 navigation.goback()부분에서 에러가 나는거였다.

그래서 혹시 goback()을 하기전에 이걸 체크하는게 있나 싶었는데 없었다. cangoback이거는 딴조건인듯

해결법은

bool _isTombstone; //톰스톤인지 아닌지 구분

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
      {
          base.OnNavigatedFrom(e);
          _isTombstone = true;
      }
 

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
      {
          base.OnNavigatedTo(e);
          _isTombstone = false;

       }

if (MessageBox.Show(msg, string.Empty, MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                    {
                        XmlGroupManager xgmInside = new XmlGroupManager();
                        xgmInside.GetData(um.GetReserveCancelUrl(StaticManager.JrnyInfoModelSelectedItem));
                        xgmInside.xdmCE.CompleteGroupDataEvent += new EventHandler<Events.XmlGroupDataEventArgs>(xdmCE_CompleteGroupDataEvent);
                        xgmInside.xdmCE.errorEvent += new EventHandler<Events.XmlDataEventArgs>(xdmCE_errorEvent);
                    }
                    else
                    {
                        if (_isTombstone == false)
                        {
                            (Application.Current.RootVisual as PhoneApplicationFrame).GoBack();
                        }
                    }

 

이런식으로 해결했다. NavigatedFrom할때 이것이 톰스톤인지 아닌지를 구분해서 goback을 할지 안할지를 구분했다

 

그리고 만약 저런식이 아닌

 

if (e.Error != null)
            {
                (Application.Current.RootVisual as PhoneApplicationFrame).GoBack();
                MessageBox.Show("네트워크를 확인해 주세요.");
                return;
            }

메세지 박스를 띄운후 goback은 절대 하지 말고

먼저 뒤로 가고 메세지 박스를 띄우는게 낫다.

Posted by 동동(이재동)
Windows Phone 72012. 2. 15. 09:49

Toolkit에서 제공하는 LongListSelector를 이용해서 만들었고

주의할점은 binding 할때 무조건 그룹쪽은 Title로 해야 한다. 

자세한설명은 소스보면 알듯

이건 테스트로 만든것이고 실제는 코레일에 예쁘게 잘만들어놓았다..


Posted by 동동(이재동)
Windows Phone 72012. 2. 8. 16:13

예를 들어 전화번호를 쓰는 textbox 가 3개가 있다고 정하자

010-xxxx-xxxx

만약 010을 쓰고 다음 textbox로 이동해야 하는데 그럴려면 중간번호 쓰는곳에 focus() 함수를 호출해야한다.

그리고 이것을 감자하기 위해서 textchanged 이벤트를 등록해야 한다.

그럼 textbox.TextChanged 이벤트를 등록하고 이동할 다음 textbox에 포커스를 등록하는등 이벤트가 엄청나게 많아지고

코드가 길어진다. 머 이것을 그냥 줄여보자.

젤 좋은 방법은

해당 Panel이 StackPanel이라면 Chidren으로 등록되어 있는 textbox의 이벤트를 한번에 등록하는 방법이 가상 이상적인 방법이지만 디자이너가 디자인을 끝낸상태라 StackPanel한개에 다 TextBox가 있는게 아니라 여러패널에 나뉘어져 있다.

그렇다면 수동적으로 일일히 코드에다가 다 써야 하는가?

그것보다는 좀 효과적으로 줄여보자.

public static class EventUtil
    {
        public static void AddFocusEvent(object Ctl1, object Ctl2)
        {
            if (Ctl1 is PhoneTextBox && Ctl2 is PhoneTextBox)
            {
                (Ctl1 as PhoneTextBox).TextChanged += (s, e) =>
                {
                    if ((Ctl1 as PhoneTextBox).Text.Length == (Ctl1 as PhoneTextBox).MaxLength)
                    {
                        (Ctl2 as PhoneTextBox).Focus();
                    }
                };
            }
            else if (Ctl1 is PhoneTextBox && Ctl2 is Button)
            {
                (Ctl1 as PhoneTextBox).TextChanged += (s, e) =>
                {
                    if ((Ctl1 as PhoneTextBox).Text.Length == (Ctl1 as PhoneTextBox).MaxLength)
                    {
                        (Ctl2 as Button).Focus();
                    }
                };
            }
        }
    }

 

사용법은

해당 페이지의 behind코드에

EventUtil.AddFocusEvent(VeteransNumTB, OkBtn);

이렇게 사용하면 된다.

textbox끼리의 focus이동과 textbox와 button과의 이벤트가 등록되어 있다.

이런 focus이벤트 등록할때는 꼭 KeyUp대신 textChanged로 해야 한다.

KeyUp이벤트로 하게 되면 사용자가 text로 가는순간 발생함으로 입력전에 focus가 변경된다.

Posted by 동동(이재동)
Windows Phone 72012. 2. 8. 10:04

코레일에서는 아이폰앱과 동일하게 WebService를 호출하기 위해서 내가 어떤 메뉴에서 웹서비스에게 호출한 URL이 아이폰과 동일하게 호출되었는지를 알고 싶을때가 있고
아이폰은 되는데 왜 윈폰은 안되나 혹시 파라미터가 다른가? 했을때 2개의 url을 비교하는 윈폰용 앱이다.
그냥 윈폼으로 만들려다가 윈폰으로 만들어보았다. 이건 테스트 프로그램임으로 ui도 없고 url도 하드코딩으로 직접 박아 놓았다. 그리고 브레이크 포인트를 걸고  watch에서 확인해야 한다.
2개의 url을 비교해서 파라미터가 다르면 watch에서 알려준다.

Posted by 동동(이재동)
Windows Phone 72012. 2. 3. 17:22

그렇다. 버그인지는 모르겟다. 두번 들어온다.

그럴때는 TextBoxChanged 이벤트보다는 KeyUp,Down 이벤트를 활용하자.

Posted by 동동(이재동)
Windows Phone 72012. 2. 3. 17:21

기본 PasswordBox 컨트롤…

일단 TextBox의 기능을 많이 제거 하였으며

무엇보다. Sealed로 되어 있어서 상속을 못한다!!!

그래서 상속받아서 나만의 컨트롤을 만들수가 없고

더 중요한건!!!

InputScope를 지원안한다는거… 어휴..

나는 Number 만 쓰는 PasswordBox를 만들고 싶었지만

윈폰에서 제공 되지 않아서 이리저리 찾아보았지만 단한개의 Numberic PasswordBox가 없었다.!!!

이럴수가?

할수없이 컨트롤을 만들었다 하지만 사용하기는 쉽지 않을것 같다.

빨리 만들려고 UserControl로 만들었다.

public partial class NumbericPasswordCtl : UserControl
   {
       StringBuilder _fakeString;

       public NumbericPasswordCtl()
       {
           InitializeComponent();
           _fakeString = new StringBuilder();
           xRealTB.Opacity = 0;
           xRealTB.KeyUp += new System.Windows.Input.KeyEventHandler(xRealTB_KeyUp);
       }

       private void xRealTB_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
       {
           if (e.Key == System.Windows.Input.Key.Unknown)
               return;

           if (e.Key == System.Windows.Input.Key.Back)
           {
               if (_fakeString.Length <= 0)
                   return;

               _fakeString.Remove(_fakeString.Length - 1, 1);
           }
           else
           {
               _fakeString.Append("*");
           }
           xFakeTB.Text = _fakeString.ToString();
       }
   }
 
    <Grid x:Name="LayoutRoot">
        <TextBlock IsHitTestVisible="False" x:Name="xFakeTB" Foreground="White" FontSize="56" />
        <TextBox InputScope="Number" x:Name="xRealTB"/>
    </Grid>

원리는 InputScope가 지원되는 TextBox위에 TextBlock를 덮어 씌우고 IsHitTestVisible을 false로 하였다.

그래서 TextBox에 숫자를 입력하지만 사용자가 보이는것은 TextBlock에 * 을 보게 될것이다.

이건 패스워드box에 워터마크를 추가하는것에 흰트를 얻었는데

Toolkit에서 지원하는 TextBox에는 Hint를 제공해주지만 PasswordBox는 지원해주지 않는다.

PasswordBox 워터마크도 비슷한 방법으로 사용할수 있다.

참고 : http://damianblog.com/2011/01/21/wp7-password-watermark/

Posted by 동동(이재동)
Windows Phone 72012. 1. 30. 20:39

코레일을 하다가 index값을 구해야 하는 경우가 생겼다.

하지만 Linq에서 where 문을 이용해서 firstOrDefault()를 이용해서 값을 얻어 왔지만 그 값이 List의 몇번째 값인지는

알수 없었다. 다른데서는 지원되는데 윈폰7의 compact .net framework에서는 제공되지 않는것인가? ㅠㅠ

그래서 여러가지 방법중 좋은 방법을 찾았다.

그 방법은 바로..두구두구두구..

그냥 직접 제작하는것이다 하하하

일단 구현한 클래스는 이렇다.

using System;
using System.Collections.Generic;

namespace GloryApp.Utils
{
    public static class IEnumerableExtensions
    {
        public static int IndexWhere<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
        {
            var enumerator = source.GetEnumerator();

            int index = 0;

            while (enumerator.MoveNext())
            {
                TSource obj = enumerator.Current;

                if (predicate(obj))

                    return index;

                index++;
            }

            return -1;
        }

        public static int IndexWhere<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)
        {
            var enumerator = source.GetEnumerator();

            int index = 0;

            while (enumerator.MoveNext())
            {
                TSource obj = enumerator.Current;

                if (predicate(obj, index))

                    return index;

                index++;
            }

            return -1;
        }
    }
}

 

그리고 위의 프레임워크를 사용할 클래스에 using 하면

var temp = siList.IndexWhere(c => c.h_srcar_no == currenSrcarNo);

이런식으로 얻어 올수 있다.

 

참고 : http://snipplr.com/view/53625/

Posted by 동동(이재동)
Windows Phone 72012. 1. 30. 18:05

보통 Linq는 List의 내용을 건드리지만

이처럼 StackPanel이나 GridPanel같은 컨트롤에서도 사용할수 있다.

예를 들어 StackPanel에 CheckBox를 add하고 그 체크박스의 특정 Content만을 뽑고 싶을땐 이렇게 한다.

var temp = SelectedSeatPanel.Children.OfType<CheckBox>().Where(c => c.Content.Equals((sender as CheckBox).Content)).FirstOrDefault();

 

바로 OfType<T>를 하면 되는것이다.

Where<(c as CheckBox) => ….)나

(CheckBox)c => …)이렇게 시도하는 초보가 없길 바란다.

Posted by 동동(이재동)
Windows Phone 72012. 1. 26. 11:34

앱을 만들다보면 페이지간의 이동이 필요한 경우가 무척이나 많다.

그럼 어떻게 해서 데이터 전송을 할까?

여러가지 방법이 있는데 헷갈려 하는 사람들이 많아서 정리해보자.

1. Global Variable을 이용하는 방법

이건 쉽고 편리하긴하다.

App.xaml에

public string SecondPageText { get; set; }

이런식으로 정의 하고

(App.Current as App).SecondPageText = txtBox.Text;

이렇게 값을 넣을수 있다.

이렇게 하거나 아니면 Static Class를 만들어서 관리하는 방법도 있다.

 

2. Query String을 이용하는 방법

이건 예전에도 포스팅했고 가장 일반적인 방법임으로 패스

그냥 Navigate할때 쿼리처럼 쓰면 된다. web같이

 

3. PhoneApplicationSerivce States를 이용하는 방법

PhoneApplicationService.Current.State["Text"] = txtBox.Text;

txtBlock.Text = (string)PhoneApplicationService.Current.State["Text"];

머 이렇게 하는법이다. 주로 tombstone할때 사용하던 방식이다.

4. NextPage intance를 이용하는 방법

OnNavigateFrom할때 미리 가는 페이지의 instace를 받아서 보내는방법

viewModel에 직접 전달해줄수도 있어서 유용할수도 있다.

아마 사람들이 잘 모르는 방법일 것이다.

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
     base.OnNavigatedTo(e);
     if (e.Content is PageOne)
     {
         (e.Content as PageOne).txtBlock.Text = txtBox.Text;
     }
}

 

윈폰7을 공부하는 사람들이 가장 궁금해 할 수 있는 부분일꺼 같아서 공유해 본다.

Posted by 동동(이재동)
Windows Phone 72012. 1. 19. 16:19

일을 하다보면 반복적인 일을 하게 된다.

예를 들면

List<MovieInfo> mi = new List<MovieInfo>();
foreach (var item in e.XmlData["rcpt_infos"] as List<Dictionary<string,object>>)
                {
                    mi.Add(new MovieInfo()
                    {
                        h_pstr_img_adr = item["h_pstr_img_adr"] as string,
                        h_abrd_dt = item["h_abrd_dt"] as string,
                        h_movie_ttl = item["h_movie_ttl"] as string,
                        h_movie_knd = item["h_movie_knd"] as string,
                        h_movie_dirtor = item["h_movie_dirtor"] as string,
                        h_movie_actor = item["h_movie_actor"] as string,
                        h_see_cl = item["h_see_cl"] as string,
                        h_scrn_tm = item["h_scrn_tm"] as string,
                        h_movie_fare = item["h_movie_fare"] as string,
                    });
                }

이코드는 xml을 읽어서 GenericList에 넣는 구문이다.

xml은 dictionary로 되어 있어서 저렇게 item[키값] 으로 넣어줘야 한다. 하지만 저것도 한두번이지

xml을 읽어오는 족족 저런 구문을 써야 한다면 코드는 늘어날것이고 유지보수 하는 사람과 코드를 짜는 사람

모두 짜증나게된다.

자 그러면 어떻게 할것인가? 저 코드를 단번에 줄여보자.

일단 MovieInfo라는 Model에는

public class MovieInfo
    {
        /// <summary>
        /// 영화 이미지
        /// </summary>
        public string h_pstr_img_adr { get; set; }

        /// <summary>
        /// 승차일
        /// </summary>
        public string h_abrd_dt { get; set; }

.

.

.

 

머 대충 이렇게 만들어졌다. 모두 string이다.

이 properties를 한번에 읽어서 set할것이다.

기존 방식은 위에처럼 mi.add(new Moveiinfo() { h_psr_img_.. = “흑흑”}); 머이렇게 반복적인 작업이 아닌 자동으로 해보자.

일단 propeties는 type으로 부터 얻어와야 한다. 간략한 예제를 보자.

MovieInfo m = new MovieInfo();
var temp = (m.GetType()).GetProperties();
temp[0].SetValue(m, "hello", null);

너무 간략하다. 코드를 설명하자면 퍼로퍼티 리스트를 가져와서 첫번째(맨위에 있는 h_pstr_img_adr)에 string 을 set한다.

원리를 알았으니  이제 맨위의 코드를 줄여보자.

자 첫번째로 줄인것이다.

 

List<MovieInfo> mi = new List<MovieInfo>();
foreach (var item in e.XmlData["rcpt_infos"] as List<Dictionary<string,object>>)
{
    MovieInfo m = new MovieInfo();
    var properties = ((new MovieInfo()).GetType().GetProperties());
    foreach (var p in properties)
    {
        p.SetValue(m, item[p.Name], null);
    }
    mi.Add(m);
}

처음에 코드랑 비교가 되는가? 노가다가 많이 줄어들었다. 하지만 이코드를 재사용할수가 없다는 단점이 있다.

왜냐하면 MovieInfo때문에.. 그렇다면 최대한 재사용을 해서 메소드를 짜보자.

 

private static object GetModelData(object o , Dictionary<string, object> item)
{
    Object m = Convert.ChangeType(o, o.GetType(), null);

    var properties = m.GetType().GetProperties();

    foreach (var p in properties)
    {
        p.SetValue(m, item[p.Name], null);
    }
    return m;
}
이건 구현부분
List<MovieInfo> mi = new List<MovieInfo>();
foreach (var item in e.XmlData["rcpt_infos"] as List<Dictionary<string,object>>)
{
    MovieInfo m = new MovieInfo();
    mi.Add(GetModelData(m, item) as MovieInfo);
}

자 이건 어떤가? 단 두줄로 끝나버렸다. 그리고 재사용까지 가능하다.

원리는 Object로 해당 Model 즉 MovieInfo를 넘기고 메소드안에서 casting한다.

Object m = Convert.ChangeType(o, o.GetType(), null);

이런식으로.  이렇게 되면 object m은 MovieInfo로 형변환이 완료 된것이다.

보이는가?  맨위의 지저분한 코드와 맨 아래의 두줄 코드의 차이가..

 

linq로 foreach로도 바꿔보았다

(e.XmlData["rcpt_infos"] as List<Dictionary<string,object>>).ForEach(item =>
{
    MovieInfo m = new MovieInfo();
    mi.Add(DataManager.GetModelData(m, item) as MovieInfo);
});

 

더 간단한가.

Posted by 동동(이재동)
Windows Phone 72012. 1. 18. 10:27

<ListBoxx:Name="ReturnTicketListBox" ItemsSource="{BindingItemSource}"Grid.Row="3"ScrollViewer.VerticalScrollBarVisibility="Hidden">
                <
ListBox.ItemTemplate>
                    <
DataTemplate>
                        <
GridHeight="87"Width="480">
                            <
Grid.ColumnDefinitions>
                                <
ColumnDefinitionWidth="148"/>
                                <
ColumnDefinitionWidth="92"/>
                                <
ColumnDefinitionWidth="80"/>
                                <
ColumnDefinitionWidth="79"/>
                            </
Grid.ColumnDefinitions>
                            <
CheckBoxIsChecked="{BindingIsChecked,Mode=TwoWay}"/>
                            <
StackPanelOrientation="Horizontal" Grid.Column="1">
                                <
TextBlockText="{Bindingh_srcar_no}"HorizontalAlignment="Center"VerticalAlignment="Center"Foreground="Black" />
                                <
TextBlockText="{Bindingh_seat_no}"HorizontalAlignment="Center"VerticalAlignment="Center"Foreground="Black" />
                            </
StackPanel>
                            <
TextBlockText="{Bindingh_ret_amt,Converter={StaticResourceMoneyConveter}}"HorizontalAlignment="Center"Grid.Column="2"VerticalAlignment="Center"Foreground="Black" />
                            <
TextBlockText="{Bindingh_ret_fee,Converter={StaticResourceMoneyConveter}}"HorizontalAlignment="Center"Grid.Column="3"VerticalAlignment="Center"Foreground="Black" />
                        </
Grid>
                    </
DataTemplate>
                </
ListBox.ItemTemplate>
            </
ListBox>

 

이렇게 itemsource를 넣고 checkbox를 twoway로 한다

<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}"/>

public class ReturnTicketModel
    {       
        public string Test { get; set; }

        public bool IsChecked { get; set; }
    }

 

모델은 그냥 이렇게 하면 된다.

너무 쉬운 부분이지만 모르는 사람은 답답할 수도 있고 code behind에서 이벤트 받아서 하는 초보적인 방법으로

할수도 있어서 포스팅 해본다.

Posted by 동동(이재동)
Windows Phone 72012. 1. 9. 19:04

디자이너가 갑자기 내가 만든 공용 UserControl에서 에러가 나서 그 UserControl 이 포함된 곳에는  블랜드에서 수정을 할수가 없었다.

블랜드에서 오류 내용을 보니

unable to determine application identity of the caller

이런 에러가 뜨고(여기서 머가 문제인지 알수가 없었다.)

그래서 비쥬얼 스튜디오에서 확인하니

Cannot create an instance of "LoginPopupControl".

이런 에러가 떳다.

빌드에는 문제가 없었고 구현에도 이상이 없었다.

문제는 TextBox에 IsolatedStorage의 값을 넣을려고 할때가 문제 였다.

예를 들면

TextBox.Text = IsolatedStorageSettings.ApplicationSettings[LoginIdKey] as string;

이렇게 하면 Xaml쪽에서 에러가 날것이다. 하지만 빌드는 잘된다.(xaml 뷰어에서 빌드하면 오류남)

이것을 해결할려면 어떻게 할것인가?

간단하다.

블랜드에서는 text값을 넣지 않으면 되는것이다.

if (System.ComponentModel.DesignerProperties.IsInDesignTool == false)
            {
                if (sm.LoginID != null)
                {
                    MemberNumberTB.Text = sm.LoginID;
                }
            }

결론은 TextBox에 Isolated값을 직접 넣지 말고 넣을려면 위의 코드처럼 분기를 타게 해줘야 한다.

참조 : http://stackoverflow.com/questions/7294461/unable-to-determine-application-identity-of-the-caller

Posted by 동동(이재동)
Windows Phone 72012. 1. 3. 21:20

예를들어 하위 UserControl 안에

public double CurrentCount { get; set; }

 

이런 property가 있다고 하자. 이것을 하위 View에서 보고 싶다. 그럴때는?

바인딩을 이렇게 하면 된다.

  <ct:SelectPersonControl Margin="10" x:Name="SPC"/>
<TextBlock Text="{Binding Path=CurrentCount, ElementName=SPC}" />

이렇게 하면 UserControl의 CurrentCount값이 바인딩 된다.

 

너무 기초인가… 혹시나 하는 마음에 알아두길~

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

회사에서 ViewModelBase(회사에서 쓰는 ViewModel dll)을 이용한다.

하지만 이건 ViewModel만들때 상속해서 써야 한다.

하지만 UserControl을 만들어 버리면 이미 UserControl을 상속받았기 때문에 ViewModelBase를 다중상속받아야 한다.

하지만 Property Binding이 목적이라면 이렇게도 쓸 수 있다.

 

#region CurrentCount

      private double _currentCount;

      /// <summary>
      ///
      /// </summary>
      public double CurrentCount
      {
          get
          {
              return _currentCount;
          }
          set
          {
              _currentCount = value;
              
              OnPropertyChanged("CurrentCount");
          }
      }

      #endregion CurrentCount

      #region Event

      /// <summary>
      /// PropertyChanged 이벤트 핸들러.
      /// </summary>
      public event PropertyChangedEventHandler PropertyChanged;

      /// <summary>
      /// OnPropertyChanged()
      /// </summary>
      /// <param name="propertyName"></param>
      protected void OnPropertyChanged(string propertyName)
      {
          if (PropertyChanged == null)
              return;
          PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }

      #endregion Event

이렇게 이벤드 핸들러를 만들어서 OnPropertyChanged를 구현한다.

Posted by 동동(이재동)
Windows Phone 72011. 12. 28. 14:22

보통 리스트 박스에 스타일을 입히기 위해서

<ListBox.ItemTemplate>
  <
DataTemplate>

이런게 DataTemplate 을 한다.

하지만 여기서 Select 했을때 특정 컨트롤 색을 바꾸고 싶거나 배경을 없애거나 머 이렇게 하고 싶었다.

블랜드로 하는게 편할거다.

ListBox에서 오른쪽 버튼을 눌러서 ItemContainerStyle을 선택후 edit/copy를 한후

코드에서 selected와 unselected코드 부분을 지웠다.(있어봤자 필요도 없음 어짜피 새로 만들꺼니)

그리고 기본적으로 포함 되어 있는 ContentControl 도 지웠다.

그리고 DataTemplate안에 있는 내용을 그대로 contentControl 를 지운부분에 삽입했다.

최종 xaml 코드이다.

<phone:PhoneApplicationPage.Resources>
        <Style x:Key="ListBoxItemStyle1" TargetType="ListBoxItem">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="BorderBrush" Value="Transparent"/>
            <Setter Property="Padding" Value="0"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Top"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border x:Name="LayoutRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal"/>
                                    <VisualState x:Name="MouseOver"/>
                                    <VisualState x:Name="Disabled">
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualState x:Name="Unselected"/>
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="image">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Collapsed</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <!--<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>-->
                            <Grid Height="106" Width="166">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="126"/>
                                    <ColumnDefinition/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="40"/>
                                    <RowDefinition/>
                                </Grid.RowDefinitions>
                                <Image Source="/GloryApp;component/Images/Ticket_GroupItem_Nor@2x.png" Stretch="Fill" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="151" Height="96" Grid.RowSpan="2" Grid.ColumnSpan="2"/>
                                <Image Grid.ColumnSpan="2" Grid.RowSpan="2" Source="/GloryApp;component/Images/Ticket_GroupItem_Sel@2x.png" Stretch="Fill" Width="151" Height="96" HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
                                <Image Source="/GloryApp;component/Images/Ticket_GroupItem_Badge_Green@2x.png" Stretch="Fill" Width="40" Height="40" Grid.Column="1" d:IsHidden="True"/>
                                <Image x:Name="image" Source="/GloryApp;component/Images/Ticket_GroupItem_Badge_Red@2x.png" Stretch="Fill" Width="40" Height="40" Grid.Column="1"/>
                                <TextBlock Text="{Binding TicketCount}" Grid.ColumnSpan="2" VerticalAlignment="Center" FontFamily="Malgun Gothic" Grid.Column="1" HorizontalAlignment="Center" FontSize="22.667" Margin="0,0,0,4" Foreground="White" />
                                <Grid Grid.ColumnSpan="2" Grid.RowSpan="2" d:DesignWidth="183" d:DesignHeight="180" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="151" Height="96" >
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="34"/>
                                        <RowDefinition Height="24"/>
                                        <RowDefinition Height="27"/>
                                        <RowDefinition/>
                                    </Grid.RowDefinitions>
                                    <TextBlock Text="{Binding h_dpt_dt}" VerticalAlignment="Bottom" HorizontalAlignment="Center" Foreground="Black" FontFamily="Malgun Gothic" />
                                    <StackPanel Orientation="Horizontal" d:LayoutOverrides="Height" Grid.Row="1" HorizontalAlignment="Center">
                                        <TextBlock Text="{Binding h_dpt_tm}" Foreground="Black" FontFamily="Malgun Gothic" FontSize="18.667" />
                                        <TextBlock Text="출발" Foreground="Black" FontFamily="Malgun Gothic" FontSize="18.667" />
                                    </StackPanel>
                                    <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Grid.Row="2" d:LayoutOverrides="VerticalAlignment" HorizontalAlignment="Center">
                                        <TextBlock Text="{Binding h_dpt_rs_stn_nm}" Foreground="Black" FontSize="18.667" FontFamily="Malgun Gothic" />
                                        <TextBlock Text="&gt;" Foreground="Black" FontSize="18.667" FontFamily="Malgun Gothic" />
                                        <TextBlock Text="{Binding h_arv_rs_stn_nm}" Foreground="Black" FontSize="18.667" FontFamily="Malgun Gothic" />
                                    </StackPanel>
                                </Grid>
                            </Grid>

                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </phone:PhoneApplicationPage.Resources>

보면 contentControl 대신 dataTemplate에 있는걸 넣었다. 그냥

그뒤 블랜드로 Status를 Selected로 해서 선택했을때에 맞게 조정하면 되는것이다.

Posted by 동동(이재동)