Korea Evangelist

Developer & Platform Evangelism, Microsoft Korea

February, 2011

  • Korea Evangelist

    Office SharePoint 2010 개발자 교육 과정

    • 0 Comments
  • Korea Evangelist

    SharePoint 한국형 탬플릿 제공

    • 0 Comments


    이미 제공되기 시작한지 시간은 좀 지났지만 여전히 많은 사람들에게 사랑 받고 있는 한국형 템플릿을 소개해 드리려고 합니다.
    기업내에서 가장 많이 활용되는 협업 방법이 바로 이메일과 게시판을 사용하는 방법입니다.
    SharePoint는 강력한 협업 솔류션을 제공하고 있으며 여기서 소개해 드리는 한국형 템플릿을 사용하시면 좀 더 한국적인 형태로 사용할 수 있게 됩니다.

    본 템플릿은 국내 업체인 네오플러스가 개발하고 Microsoft가 배포하는 것으로 추가적인 기술 지원은 제공되지 않는 버전입니다.

    하지만 궁금한 사항은 SharePoint Korea (http://cafe.naver.com/spsv3)에서 도움을 받을 수 있을 것 같습니다.
    감사합니다.

    http://youngwook.com/502 에서 다운로드 하실 수 있습니다.

  • Korea Evangelist

    모다의 윈도우폰7 뚝딱 팩토리(16)-영상과 음악 활용하기

    • 0 Comments

     

    한국마이크로소프트에서 초급 스마트폰 개발자 분들을 위해 공개하는 모다의 윈도우폰7 뚝딱 팩토리 열여섯번째 영상!

    멀티미디어 기기로서의 기능이 더더욱 강조되고 있는 모바일 디바이스에서는 다양한 영상과 음악을 활용해서 어플리케이션을 만들 수 있습니다. 쉬운 개발환경을 지원하는 윈도우폰 답게 멀티미디어의 추가는 비주얼 스튜디오에서 드래그 몇 번으로 금방 만들 수 있게 됩니다. 또한 정지/재생/일시정지 등의 간단한 제어 역시 코드 한 줄로 해결이 되지요.

    이러한 기능 외에도 컨트롤의 사이즈에 맞게 자동 조정을 해 주는 속성을 지정해 줄 수도 있으며, 로컬 파일이 아닌 인터넷상의 파일도 간단한 소스코드 수정으로 쉽게 구현이 가능합니다.

    하지만 영상/음성을 저장하는 포맷은 다양한 형태로 존재하고 있습니다. 윈도우폰에서도 다양한 포맷을 지원하고는 있지만, 모든 포맷을 지원하고 있지 않으니 어플리케이션을 제작하실 때 지원되는 포맷인지 확인 하신 후 그대로 사용하시거나 적절한 포맷으로 인코딩을 해 주시면 됩니다.

       1:  using System;
       2:  using System.Collections.Generic;
       3:  using System.Linq;
       4:  using System.Net;
       5:  using System.Windows;
       6:  using System.Windows.Controls;
       7:  using System.Windows.Documents;
       8:  using System.Windows.Input;
       9:  using System.Windows.Media;
      10:  using System.Windows.Media.Animation;
      11:  using System.Windows.Shapes;
      12:  using Microsoft.Phone.Controls;
      13:   
      14:  namespace mediaTest
      15:  {
      16:      public partial class MainPage : PhoneApplicationPage
      17:      {
      18:          // Constructor
      19:          public MainPage()
      20:          {
      21:              InitializeComponent();
      22:   
      23:              //mediaElement1.Play();
      24:          }
      25:   
      26:          private void button1_Click(object sender, RoutedEventArgs e)
      27:          {
      28:              mediaElement1.Play();
      29:          }
      30:   
      31:          private void button2_Click(object sender, RoutedEventArgs e)
      32:          {
      33:              mediaElement1.Pause();
      34:          }
      35:   
      36:          private void button3_Click(object sender, RoutedEventArgs e)
      37:          {
      38:              mediaElement1.Stop();
      39:          }
      40:      }
      41:   
      42:  }

     

    이번 영상에서 보여드린 예제 외에도 윈도우폰에서는 마이크로폰을 활용하거나 Music+Video Hub와 연동을 하는 등 단순 재생정지 외에도 다양한 기능들을 활용할 수 있습니다. 자세한 내용은 MSDN 라이브러리에서 확인이 가능합니다.

    어느덧 16화에 걸친 뚝딱 팩토리도 마감하게 되었네요. 그 동안 올라온 영상들은 유튜브의 동영상 리스트에서 한번에 보실 수 있고, 여러가지 의견과 문의 사항들은 공식 팬 페이지를 통해 받고 있습니다. 함께 해 주셔서 감사드리고 여러분들께서 제작하시는 멋진 어플리케이션 기대하겠습니다!

     

  • Korea Evangelist

    모다의 윈도우폰7 뚝딱 팩토리(15)-세련된 터치 제어하기

    • 0 Comments

     

    한국마이크로소프트에서 초급 스마트폰 개발자 분들을 위해 공개하는 모다의 윈도우폰7 뚝딱 팩토리 열다섯번째 영상!

    스마트폰에서 터치를 제어한다는 것은 매우 중요한 일입니다. 특히 스마트폰 인터페이스가 발전하면서 사용자 경험(UX: User Experience) 측면이 많이 강조가 되고 있는데, 이러한 UX를  터치를 향상시키기 위해 많이 활용하는 것이 다양한 터치패턴(제스쳐)을 활용하는 것입니다.

    윈도우폰에서 터치를 인식하는 것은 이벤트 핸들러로도 충분히 할 수 있지만, 조금 더 나아가 멀티 터치를 한다거나, 아니면 터치의 궤적을 추적한다거나 하는 기능이 필요한 어플리케이션을 개발하려고 하면 조금 복잡해져서 단순 이벤트 핸들러에서는 이를 처리할 수 없게 됩니다.
    터치를 통해 여러 가지 제어를 하는것을 윈도우폰에서는 Manipulation이라고 하는데요, 윈도우폰에서는 이와 관련된 이벤트를 3가지 제공하고, 흐름을 추적할 수 있는 개발환경을 지원합니다. 터치 흐름 추적과 관련된 이벤트로는 ManipulationStarted / ManipulationDelta / ManipulationCompleted 가 있으며, 이름에서 짐작이 가능하듯이 각각 터치를 막 시작했을때(스크린에 손을 대는 순간), 그리고 손을 댄 이후부터 손을 때기 직전까지, 그리고 손을 때는 순간에 걸쳐 3번 이벤트가 발생하게 됩니다.

    그리고, 터치 흐름을 추적하는 방법도 있는데요, 터치는 2차원의 스크린 위에서 이루어 지므로 2차원 좌표계를 이용하게 됩니다. 특히 터치 흐름은 ManipulationDelta 이벤트가 일어나는 과정중에 추적해야 하므로 ManipulationDelta 이벤트로 생성한 메서드에서만 사용이 가능하고요, e.DeltaManipulation.Translation.X / Y 를 통해 터치의 2차원 추적이 가능합니다. 이렇게 손가락 하나의 흐름을 추적하는 것 외에도 손가락 2개, 즉 멀티터치의 궤적을 추적할 수 있는데요, 역시 2차원 좌표계를 이용해 두 손가락 사이의 위치 변화를 감지합니다. 이것 역시 ManipulationDelta 이벤트로 생성한 메서드 안에서 e.DeltaManipulcation.Scale.X / Y 를 이용해서 추적할 수 있습니다.
    또한 이번 예제에서 터치기능을 이용해 구현 한 것이 바로 도형의 위치와 크기를 변화시키는 어플리케이션인데요, TranslateTransform 클래스를 이용해 도형의 위치제어를, ScaleTransform 클래스를 이용해 도형의 크기제어를 할 수 있습니다. 이것을 이용해 터치추적-도형모영 제어를 연동할 수 있는데요, 다음 코드와 같이 누적덧셈/곱셈 연산을 통해 제어가 가능합니다.

    translation.X += e.DeltaManipulation.Translation.X

    보시다시피 상당히 직관적이고 편리한 터치제어 환경을 지원하고 있습니다. 이번 예제는 간단하게 도형의 변화 정도만을 다루었지만 이것을 이용해 사용자만의 제스쳐를 구현한다거나, 이미지 편집 프로그램을 구현할 수 있겠지요.

     

       1:  using System;
       2:  using System.Collections.Generic;
       3:  using System.Linq;
       4:  using System.Net;
       5:  using System.Windows;
       6:  using System.Windows.Controls;
       7:  using System.Windows.Documents;
       8:  using System.Windows.Input;
       9:  using System.Windows.Media;
      10:  using System.Windows.Media.Animation;
      11:  using System.Windows.Shapes;
      12:  using Microsoft.Phone.Controls;
      13:   
      14:  namespace ManupulationTest
      15:  {
      16:      public partial class MainPage : PhoneApplicationPage
      17:      {
      18:          TranslateTransform translation;
      19:          TransformGroup transformGroup;
      20:          ScaleTransform scale;
      21:   
      22:          // Constructor
      23:          public MainPage()
      24:          {
      25:              InitializeComponent();
      26:   
      27:              transformGroup = new TransformGroup();
      28:              translation = new TranslateTransform();
      29:              scale = new ScaleTransform();
      30:   
      31:              transformGroup.Children.Add(translation);
      32:              transformGroup.Children.Add(scale);
      33:   
      34:              rectangle1.RenderTransform = transformGroup;
      35:   
      36:              ManipulationStarted += new EventHandler<ManipulationStartedEventArgs>(MainPage_ManipulationStarted);
      37:              ManipulationDelta += new EventHandler<ManipulationDeltaEventArgs>(MainPage_ManipulationDelta);
      38:              ManipulationCompleted += new EventHandler<ManipulationCompletedEventArgs>(MainPage_ManipulationCompleted);
      39:          }
      40:   
      41:          void MainPage_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e)
      42:          {
      43:              //throw new NotImplementedException();
      44:              rectangle1.Fill = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
      45:          }
      46:   
      47:          void MainPage_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
      48:          {
      49:              //throw new NotImplementedException();
      50:              translation.X += e.DeltaManipulation.Translation.X;
      51:              translation.Y += e.DeltaManipulation.Translation.Y;
      52:   
      53:              if (e.DeltaManipulation.Scale.X != 0)
      54:                  scale.ScaleX *= e.DeltaManipulation.Scale.X;
      55:              if (e.DeltaManipulation.Scale.Y != 0)
      56:                  scale.ScaleY *= e.DeltaManipulation.Scale.Y;
      57:          }
      58:   
      59:          void MainPage_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
      60:          {
      61:              // throw new NotImplementedException();
      62:              rectangle1.Fill = new SolidColorBrush(Color.FromArgb(127, 255, 0, 0));
      63:          }
      64:      }
      65:   
      66:  }

     

  • Korea Evangelist

    모다의 윈도우폰7 뚝딱 팩토리(14)-LINQ to XML을 이용한 RSS 리더 만들기

    • 0 Comments

     

     

    한국마이크로소프트에서 초급 스마트폰 개발자 분들을 위해 공개하는 모다의 윈도우폰7 뚝딱 팩토리 열네번째 영상!

    데이터를 “저장하는 기술”도 중요하지만 데이터를 저장하는 “형태” 역시 중요합니다. 그리고 이것을 “해석하는 기술” 역시 중요하죠. 3박자가 모두 맞아 떨어져야 멋진 어플리케이션이 만들어 지고 사용하시는 분들을 감동시킬 수 있죠.

    이번에 다룰 내용은 바로 마지막에 해당하는 데이터를 해석하는 기술입니다. 마이��로소프트에서는 데이터를 해석하는 기술중의 하나인 LINQ(Language Integrated Query)를 제공하고 있으며 이번 영상에서 다루어 볼 내용은 LINQ를 이용해 XML문서를 해석하는 LINQ to XML 입니다. 그리고 이 기술을 적용하기 위해 이번 영상에서 예제로 들고 있는것이 바로 RSS이지요. 윈도우폰 공식 블로그의 RSS를 이용해 윈도우폰에서 열어보는 약간 복잡하지만 유용한 예제를 보여드립니다.

    RSS는 XML 1.0 스팩을 이용하고 있으며, XML을 해석하기 위해서는 System.Xml.Linq 네임 스페이스를 Add Reference 기능을 이용해 추가한 다음 이용하셔야 합니다. 그리고 XML의 형태에 맞게 맵핑을 해서 사용할 수가 있지요. LINQ로 해석하는 부분은 다음과 같습니다.

     

     var rssList = from rssTree in rssParser.Descendants("item")
        select new BlogPost
        {
            Title = rssTree.Element("title").Value,
            Contents = rssTree.Element("description").Value ,
            Url = rssTree.Element("link").Value
        };

     

    이 코드는 미리 만들어 진 BlogPost 클래스의 Title / Contents / Url Property에 각각 <title></title> / <description></description> / <link></link> 태그 안에 포함 된 내용을 맵핑하는 부분입니다. 참고로 BlogPost 클래스의 선언은 다음과 같이 되어 있습니다. 맵핑용 클래스를 선언하실 때는 항상 접근이 용이하도록 public / get / set 등을 적절히 선언해 주셔야 합니다.

     

      public class BlogPost 
      {
        public string Title { get; set; }
        public string Contents { get; set; }
        public string Url { get; set; }
      }

     

    또한 이전에 보여드렸던 Data Binding에서 조금 더 발전된 방법을 보여드리고 있는데요, 직접적으로 ListBox 안에 들어가는 형태와 데이터를 직접 커스터마이징하는 방법을 담았습니다. XAML코드에서 ListBox 안에 출력할 템플릿을 추가하는 방법은 다음과 같습니다. 아래 코드에서 {Binding Title} / {Binding Contents} 부분은 앞서 적어드린 BlogPost 상의 Property 이름과 동일하게 적어주시면 됩니다. 그리고 이를 연동하실 때는 listBox1.ItemsSource = rssList 로 코딩 해 주시면 됩니다.

     

    <ListBox Height="498" HorizontalAlignment="Left" Name="listBox1" VerticalAlignment="Top" Width="456" SelectionChanged="listBox1_SelectionChanged">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical" Margin="0,0,0,10">
                    <TextBlock Text="{Binding Title}" Foreground="#FFE0C000" FontSize="30" />
                    <TextBlock Text="{Binding Contents}" TextWrapping="Wrap" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

     

    이 외에도 로딩중 표시하기(ProgressBar), Linked List 활용하기 등 여러가지 기술들이 이번 동영상에 녹아있고 특히 Data Binding과 LINQ to XML은 윈도우폰 어플리케이션을 개발하는 데 있어서 단골로 사용하는 기술들입니다. 이번 영상이 많은 도움이 되시길 바랍니다.

     

       1:  using System;
       2:  using System.Collections.Generic;
       3:  using System.Linq;
       4:  using System.Net;
       5:  using System.Windows;
       6:  using System.Windows.Controls;
       7:  using System.Windows.Documents;
       8:  using System.Windows.Input;
       9:  using System.Windows.Media;
      10:  using System.Windows.Media.Animation;
      11:  using System.Windows.Shapes;
      12:  using Microsoft.Phone.Controls;
      13:   
      14:  using System.Xml.Linq;
      15:  using Microsoft.Phone.Tasks;
      16:   
      17:  namespace rssParserTest01
      18:  {
      19:      public partial class MainPage : PhoneApplicationPage
      20:      {
      21:          List<BlogPost> blogPosts = new List<BlogPost>();
      22:   
      23:          // Constructor
      24:          public MainPage()
      25:          {
      26:              InitializeComponent();
      27:          }
      28:   
      29:          private void button1_Click(object sender, RoutedEventArgs e)
      30:          {
      31:              progressBar1.Visibility = System.Windows.Visibility.Visible;
      32:              progressBar1.IsIndeterminate = true;
      33:   
      34:              WebClient rssDownloader = new WebClient();
      35:              rssDownloader.DownloadStringAsync(new Uri("http://blogs.msdn.com/b/jinhoseo/rss.aspx"));
      36:              rssDownloader.DownloadStringCompleted += new System.Net.DownloadStringCompletedEventHandler(rssDownloader_DownloadStringCompleted);
      37:          }
      38:   
      39:          void rssDownloader_DownloadStringCompleted(object sender, System.Net.DownloadStringCompletedEventArgs e)
      40:          {
      41:              // throw new NotImplementedException();
      42:              string rssContent = e.Result;
      43:   
      44:              XDocument rssParser = XDocument.Parse(rssContent);
      45:   
      46:              //LINQ
      47:              var rssList = from rssTree in rssParser.Descendants("item")
      48:                            select new BlogPost
      49:                            {
      50:                                Title = rssTree.Element("title").Value,
      51:                                Contents = rssTree.Element("description").Value ,
      52:                                Url = rssTree.Element("link").Value
      53:                            };
      54:   
      55:              listBox1.ItemsSource = rssList;
      56:              blogPosts = rssList.ToList();
      57:              progressBar1.Visibility = System.Windows.Visibility.Collapsed;
      58:          }
      59:   
      60:          private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
      61:          {
      62:              WebBrowserTask blogViewer = new WebBrowserTask();
      63:              blogViewer.URL = blogPosts[listBox1.SelectedIndex].Url;
      64:              blogViewer.Show();
      65:          }
      66:      }
      67:   
      68:      public class BlogPost 
      69:      {
      70:          public string Title { get; set; }
      71:          public string Contents { get; set; }
      72:          public string Url { get; set; }
      73:      }
      74:  }

       1:  <phone:PhoneApplicationPage 
       2:      x:Class="rssParserTest01.MainPage"
       3:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       4:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       5:      xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
       6:      xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
       7:      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
       8:      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
       9:      mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
      10:      FontFamily="{StaticResource PhoneFontFamilyNormal}"
      11:      FontSize="{StaticResource PhoneFontSizeNormal}"
      12:      Foreground="{StaticResource PhoneForegroundBrush}"
      13:      SupportedOrientations="Portrait" Orientation="Portrait"
      14:      shell:SystemTray.IsVisible="True">
      15:   
      16:      <!--LayoutRoot is the root grid where all page content is placed-->
      17:      <Grid x:Name="LayoutRoot" Background="Transparent">
      18:          <Grid.RowDefinitions>
      19:              <RowDefinition Height="Auto"/>
      20:              <RowDefinition Height="*"/>
      21:          </Grid.RowDefinitions>
      22:   
      23:          <!--TitlePanel contains the name of the application and page title-->
      24:          <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
      25:              <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
      26:              <TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
      27:          </StackPanel>
      28:   
      29:          <!--ContentPanel - place additional content here-->
      30:          <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
      31:              <Button Content="Button" Height="97" HorizontalAlignment="Left" Margin="6,504,0,0" Name="button1" VerticalAlignment="Top" Width="450" Click="button1_Click" />
      32:              <ListBox Height="498" HorizontalAlignment="Left" Name="listBox1" VerticalAlignment="Top" Width="456" SelectionChanged="listBox1_SelectionChanged">
      33:                  <ListBox.ItemTemplate>
      34:                      <DataTemplate>
      35:                          <StackPanel Orientation="Vertical" Margin="0,0,0,10">
      36:                              <TextBlock Text="{Binding Title}" Foreground="#FFE0C000" FontSize="30" />
      37:                              <TextBlock Text="{Binding Contents}" TextWrapping="Wrap" />
      38:                          </StackPanel>
      39:                      </DataTemplate>
      40:                  </ListBox.ItemTemplate>
      41:              </ListBox>
      42:              <ProgressBar Height="4" HorizontalAlignment="Left" Margin="10,200,0,0" Name="progressBar1" VerticalAlignment="Top" Width="460" Visibility="Collapsed" />
      43:          </Grid>
      44:      </Grid>
      45:  </phone:PhoneApplicationPage>

     

Page 1 of 4 (17 items) 1234