Window/WPF2010. 4. 29. 09:16

플래쉬 객체를 WPF에 포함시킨 후

플래쉬 객체 위에 WPF 객체를 포함시켜야 할 경우가 있습니다.

 

ElementHost를 사용하여 WPF 객체를 포함시킬 수가 있는데요.

 

이 경우 포함 시킨 객체가 보이지 않는 현상이 발생합니다.

이것은 윈폼에 컨트롤을 포함시키는 과정에서 처음 포함된 객체가 제일 앞에 있기 때문에

플래쉬 객체에 가려져 보이지 않는 것입니다.

 

간단하게 현재 포함된 객체를 플래쉬 객체보다 앞으로 나오게 하면 해결 할 수 있습니다.

 

다음 소스 예제는

윈폼의 BringToFront 함수를 사용하여 제일 앞으로 나오게 하였습니다.

 public void SetWpfControl(FrameworkElement control, int x, int y)

  {

     ElementHost host = new ElementHost();

     host.Width = (int)control.Width;

     host.Height = (int)control.Height;

 

     host.Child = (UIElement)control;

     host.Location = new System.Drawing.Point(x, y);

 

     flash.Controls.Add(host);

     host.BringToFront();

 }

 

실행화면과 같이 플래쉬 객체 위에 WPF 객체가 올려지는 것을 확인할 수 있습니다.

 

'Window > WPF' 카테고리의 다른 글

[ WPF ] 이미지 그림판  (2) 2010.05.08
[ WPF ] UI 쓰레드 변경하기  (0) 2010.05.04
[ WPF ] 클래스 구조  (0) 2010.04.27
[ WPF ] Flash in WPF  (3) 2010.04.23
[ WPF ] 캡쳐보드 카메라 사용하기  (0) 2010.04.22
Posted by 열ㅇl
Window/WPF2010. 4. 27. 10:26

'Window > WPF' 카테고리의 다른 글

[ WPF ] UI 쓰레드 변경하기  (0) 2010.05.04
[ WPF ] WPF in Flash  (0) 2010.04.29
[ WPF ] Flash in WPF  (3) 2010.04.23
[ WPF ] 캡쳐보드 카메라 사용하기  (0) 2010.04.22
[ WPF ] Using WPF in Winform  (0) 2010.03.12
Posted by 열ㅇl
Window/WPF2010. 4. 23. 16:16

WPF에서 Flash 컨트롤을 사용하는 간단한 예제에 대해 포스팅 하겠습니다.

 

1) WPF 응용 프로그램 생성.

 

2) 사용자 지정 컨트롤 라이브러리 프로젝트 추가.

 

3) Winform 사용자 정의 컨트롤 추가.

 

4) 디자인 창 도구상자에서 마우스 오른쪽 버튼을 눌러 항목 선택 클릭

 

5) COM 탭에 Shocwave Flash 선택

 

6) Shockwave Flash Object 삽입

 

7) 코드 내용


8) WPF 사용자 정의 컨트롤 추가

 

9) 코드 내용



10) 사용자 지정 컨트롤 라이브러리 프로젝트 빌드 후,

     응용 프로그램에서 dll 참조 추가

 

11) 코드 내용



12) 실행화면

 

'Window > WPF' 카테고리의 다른 글

[ WPF ] WPF in Flash  (0) 2010.04.29
[ WPF ] 클래스 구조  (0) 2010.04.27
[ WPF ] 캡쳐보드 카메라 사용하기  (0) 2010.04.22
[ WPF ] Using WPF in Winform  (0) 2010.03.12
[ WPF ] 옆으로 흐르는 TextBlock  (0) 2010.03.11
Posted by 열ㅇl
Window/WPF2010. 4. 22. 21:04

WPF에서 웹캠을 사용하기 위해 DirectShow를 이용한 방법들이 많이 있습니다.

 

캡쳐보드에 연결된 카메라를 인식하기 위해서

여러 자료를 검색한 결과,

다음의 컨트롤만이 가능하였습니다.

 

제작자의 블로그 : http://jmorrill.hjtcentral.com/Home/tabid/428/EntryId/15/WPF-Hackery-Part-I.aspx

소스코드 : http://videorendererelement.codeplex.com/SourceControl/list/changesets

 

최근 소스코드를 다운 받으신 후,

cmd 창을 열어 압축을 해제한 폴더의

BinRelease 경로로 들어가 regsvr32  DShowMediaBridge.ax 명령을 실행시켜 등록시킵니다.

 

상용화 프로그램에서 보여주는 화면을 별도로 제작중인 프로그램에서

보여주기 위해서 다음의 코드 수정을 하였습니다.

 

CaptureDevice 클래스의

SetupGraph 함수의 capGraph.RenderStream(PinCategory.Capture , MediaType.Video, capFilter, null, baseGrabFlt); 부분과

SetConfigParms 함수의 capGraph.FindInterface(PinCategory.Capture , MediaType.Video, capFilter, typeof(IAMStreamConfig).GUID, out o); 부분의 PinCategory.Capture 부분을 PinCategory.Preview로 바꾸면 됩니다.

 

< 실행화면 >

 

기타 참고 사이트 :

http://directshownet.sourceforge.net/

http://www.aforgenet.com/

 

 

'Window > WPF' 카테고리의 다른 글

[ WPF ] 클래스 구조  (0) 2010.04.27
[ WPF ] Flash in WPF  (3) 2010.04.23
[ WPF ] Using WPF in Winform  (0) 2010.03.12
[ WPF ] 옆으로 흐르는 TextBlock  (0) 2010.03.11
[ WPF ] Page간 데이터 전달  (0) 2010.03.06
Posted by 열ㅇl
Window/WPF2010. 3. 12. 16:53

WPF 컨트롤을 Winform 내부에 포함시키기 위해서는

ElementHost 클래스를 사용할 수 있습니다.

 

ElementHost 클래스는 System.Windows.Forms.Control을 상속받은 윈폼 컨트롤로

WPF 엘리먼트를 포함시킬 수 있도록 특화된 클래스입니다.

 

자, 이제 하나 하나 알아보겠습니다.

 

우선 윈폼 프로젝트를 생성 후 다음과 같이 참조 추가를 선택 하여,

 

 

WindowsFormIntegration.dll 을 추가합니다.

 

그럼 이제 포함 방법들에 대해 알아보겠습니다.

 

1) C# 코드

 

코드로만 작성 시엔 PresentationCore.dll, PresentationFramework.dll을 추가 후

 

다음과 같이 네임스페이스를 추가합니다.

 

using System.Windows.Controls;

using System.Windows.Forms.Integration;

 

간단하게 WPF 컨트롤 중 버튼을 추가해보겠습니다.

 

 ElementHost host = newElementHost();

 

 System.Windows.Controls.Button btn = new System.Windows.Controls.Button();

 btn.Content = "WPF Button!!";

 

 host.Child = btn;

 host.Location = newPoint(45, 10);

 

 this.Controls.Add(host); 

 

System.Windows.Controls.Button과 System.Windows.Forms.Button 사이의 모호성 때문에

위와 같이 정확한 타입을 명시해야 합니다.

 

2) 도구 상자

 

윈폼 창을 선택 후 도구상자를 열어 ElmentHost 선택하여 윈폼 안에 위치시킵니다.

자동으로 PresentationCore.dll, PresentationFramework.dll이 추가됩니다.

    

 

간단한 TextBlock을 추가해 보겠습니다.

 

 TextBlock tb = newTextBlock();

 tb.Text = "WPF TextBlock!!";

 

 elementHost1.Child = tb;

 

3) WPF UserControl

 

우선 UserControl을 생성하겠습니다.

 

Xaml 의 내용은 간단하게 버튼을 위치시킨 후 Click 이벤트를 주었습니다.

 <Grid>
     <Button Click="Button_Click">
         WPFControl!!
     </Button>
 </Grid
>
 

 privatevoid Button_Click(object sender, RoutedEventArgs e)

 {

     MessageBox.Show("WPF Button!!");

 }

 

윈폼에 ElementHost 를 올려 놓은 뒤 ◀를 눌러 WPFControl 목록을 선택합니다. 


4) 윈폼 컨트롤을 포함한 WPF 컨트롤 포함하기

 

이번엔 윈폼 컨트롤인 MonthCalendar를 포함하는 WPF Button 컨트롤을 포함해 보겠습니다.

WindowsFormsHost 의 Child로 MonthCalendar를 포함 후

Button의 Content로 추가하였습니다.

 

 WindowsFormsHost wHost = newWindowsFormsHost();

 wHost.Child = newMonthCalendar();

 

 System.Windows.Controls.Button btn1 = new System.Windows.Controls.Button();

 

 btn1.Content = wHost;

 elementHost3.Child = btn1;

 

자 지금까지의 결과를 확인해 보겠습니다.

   

 

Using WPF in Winform.zip

'Window > WPF' 카테고리의 다른 글

[ WPF ] Flash in WPF  (3) 2010.04.23
[ WPF ] 캡쳐보드 카메라 사용하기  (0) 2010.04.22
[ WPF ] 옆으로 흐르는 TextBlock  (0) 2010.03.11
[ WPF ] Page간 데이터 전달  (0) 2010.03.06
[ WPF ] 간단한 Image Animation  (2) 2010.02.12
Posted by 열ㅇl
Window/WPF2010. 3. 11. 18:09

이번 포스팅에서는

TV를 보면 자막이 옆으로 흐르는 것 같은 애니메이션을

TextBlock을 이용해 비하인드 코드로 구현하는 방법에 대해 알아보겠습니다.

 

예제는 다음과 같이 Grid와 Canvas에 대해 작성해 보았습니다.

 

 

주의 할 점은 Grid 패널은 자식 요소의 크기를

자신의 크기에 맞게 변경해 버리기 때문에 Text 의 길이가 Grid 패널의

사이즈를 넘어 갈 경우 짤리는 현상이 발생합니다.

 

이를 방지 하기 위해 오버되는 Text의 길이 만큼 Margin 의 Right 값을 변경합니다.

 

소스는 다음과 같습니다.

간단히 TranslateTransform 의 x 값을 변경하는 내용입니다.

  private void TranslateAnimation(TextBlock text, double time)

 {

    double right = 0;

    FrameworkElement parent = text.Parent as FrameworkElement;

 

    // 텍스트의 길이가 부모 패널을 넘어갈 때

    if (text.ActualWidth > parent.ActualWidth)

    {

        right = text.ActualWidth - parent.ActualWidth;

    }

 

    // 부모 패널이 Grid라면 Margin 값 변경

    // 텍스트가 잘리는 현상 방지

    if (parent is Grid)

    {

        text.Margin = new Thickness(0, 0, -right, 0);

    }

 

    // TranslateTransform을 생성해야 애니메이션 적용

    text.RenderTransform = new TranslateTransform();

 

    Storyboard story = new Storyboard();

 

    DoubleAnimation animation = new DoubleAnimation();

 

    animation.From = parent.ActualWidth;

    animation.To = -(parent.ActualWidth + right);

    animation.Duration = TimeSpan.FromSeconds(time);

    animation.RepeatBehavior = RepeatBehavior.Forever;

 

    // TranslateTransform.XProperty 값 설정

    DependencyProperty[] Dproperty = new DependencyProperty[]

    {

        TextBlock.RenderTransformProperty,

        TranslateTransform.XProperty

    };

 

    string path = "(0).(1)";

 

    Storyboard.SetTargetProperty(animation, new PropertyPath(path, Dproperty));

    story.Children.Add(animation);

    story.Begin(text);

 }

 

'Window > WPF' 카테고리의 다른 글

[ WPF ] 캡쳐보드 카메라 사용하기  (0) 2010.04.22
[ WPF ] Using WPF in Winform  (0) 2010.03.12
[ WPF ] Page간 데이터 전달  (0) 2010.03.06
[ WPF ] 간단한 Image Animation  (2) 2010.02.12
[ WPF ] Canvas Image Background  (0) 2010.02.11
Posted by 열ㅇl
Window/WPF2010. 3. 6. 02:34

Page간 데이터를 전달하는 방법에 대해 알아보겠습니다.

 

예제는

첫 페이지에서 색상을 골라 다음 페이지로 값을 전달하는 3가지 방법과

현재 페이지의 값을 이전 페이지로 반환시키는 방법에 대한 내용입니다.

 

          

 

         

 

① 객체 매개변수를 받아들이는 Navigate

Navigate메소드는 Page의 인스턴스와 Uri뿐 아니라 어떤 것이든 전달 대상 페이지에 전송할 수 있습니다.

 

다음 소스와 같이 이동할 페이지의 인스턴스와 전달하려는 값을 넘길 수가 있습니다.

 // 전송할 객체를 매개변수로 넘겨줍니다.

private void ObjectNavigate(object sender, RoutedEventArgs e)   

{

    ColorPage colorPage = new ColorPage();

    // NavigationService의 LoadCompleted 이벤트 연결

    colorPage.SetLoadCompleted(NavigationService);

 

    this.NavigationService.Navigate(colorPage, color);

}

 

SetLoadCompleted의 함수 내용은 단순히 넘어온 NavigationService의 LoadCompleted 이벤트를

연결시켜줍니다.

public void SetLoadCompleted(NavigationService navigation)

{

    navigation.LoadCompleted += new LoadCompletedEventHandler(NavigationService_LoadCompleted);

}

 

이와 같은 이유는 아래 그림과 같이 페이지 이동 시 일어나는 이벤트의 발생 순서에 따라

Page의 Loaded 이벤트가 발생하기 전에 LoadCompleted이벤트가 발생하기 때문입니다.

 

LoadCompleted 이벤트에서는 ExtraData값으로 넘겨받은 매개변수를 사용할 수 있습니다.

 // 매개변수로 넘어온 값을 사용합니다.

void NavigationService_LoadCompleted(object sender, NavigationEventArgs e)

{

    if (e.ExtraData != null)

    {

        this.color.Fill = (Brush)converter.ConvertFromString((string)e.ExtraData);

    }

 

    this.NavigationService.LoadCompleted -= new LoadCompletedEventHandler(NavigationService_LoadCompleted);

}

 

② Instance만 사용하는 Navigate

오버로드 생성자를 사용하는 단순한 방법입니다.

매개변수의 데이터 타입을 정확히 할 수 있고, 프레임웍 차원에서 타입을 보증하기 때문에

데이터를 체크할 필요가 없는 장점이 있습니다.

 // 오버로드된 생성자의 인자로 넘겨 받습니다.

public ColorPage(string color)

{

    InitializeComponent();

 

    this.color.Fill = (Brush)converter.ConvertFromString(color);

}

 

 // 생성자의 매개변수로 넘겨줍니다.

private void InstanceNavigate(object sender, RoutedEventArgs e)

{

    this.NavigationService.Navigate(new ColorPage(color));

}

 

③ Application.Properties를 이용한 전역 데이터

여러 페이지에서 공유하기 위한 방법으로 사용할 수 있지만 안정성이 부족한 단점이 있습니다.

 // 전역 데이터로 공유합니다.

private void ApplicationProperties(object sender, RoutedEventArgs e)

{

    Application.Current.Properties["color"] = color;

}

 

 // 전역데이터를 사용합니다.

private void Page_Loaded(object sender, RoutedEventArgs e)

{

    if (Application.Current.Properties["color"] != null)

    {

        this.color.Fill = (Brush)converter.ConvertFromString((string)Application.Current.Properties["color"]);

        Application.Current.Properties.Remove("color");

    }

}

 

④ PageFunction

다음 그림과 같이 현재 페이지에서 작업을 처리하고

이전페이지로 돌아갈 때 처리 결과를 반환할 경우가 생깁니다.

 

 

위의 방법들을 사용할 수도 있겠지만 항상 새로운 Instance를 생성하기 때문에 문제가 발생할 수 있습니다.

WPF는 PageFunction 클래스를 사용하여 안정적이고 뒤로가기 버튼을 누른 것처럼 자동으로 이동할 수 있습니다.

 <PageFunction
   xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    x:Class="WpfApplication1.PageFunction1"
    x:TypeArguments="sys:String"
    Title="PageFunction1">
  <Grid>

  </Grid>
</PageFunction>

 

x:TypeArguments="sys:String"의 구문이 사용되었습니다.

PageFunction은 PageFunction<T> 타입의 제너릭 클래스이기 때문에 반환되는 값의 타입을 명시해야 합니다.
이는 타입 안전성을 확보한다는 점이 있습니다.

 

다음과 같이 Ruturn 이벤트를 통해 반환값을 받을 수 있습니다.

 // PageFunction 테스트

private void Hyperlink_Click(object sender, RoutedEventArgs e)

{

    PageFunction1 page = new PageFunction1();

    page.Return += new ReturnEventHandler<string>(page_Return);

    this.NavigationService.Navigate(page);

}

 

void page_Return(object sender, ReturnEventArgs<string> e)

{

    ((PageFunction1)sender).Return -= page_Return;

 

    result.Text = "Message : " + e.Result;

}

 

PageFunction 클래스는 OnReturn 메소드를 호출해서 반환되는 데이터를 다음과 같이 ReturnEventArgs타입으로

래핑하여 전달할 수 있습니다.

 private void Button_Click(object sender, RoutedEventArgs e)

{

    OnReturn(new ReturnEventArgs<string>(input.Text));

}

 

'Window > WPF' 카테고리의 다른 글

[ WPF ] Using WPF in Winform  (0) 2010.03.12
[ WPF ] 옆으로 흐르는 TextBlock  (0) 2010.03.11
[ WPF ] 간단한 Image Animation  (2) 2010.02.12
[ WPF ] Canvas Image Background  (0) 2010.02.11
[ WPF ] TextBox Select All Text  (0) 2010.02.11
Posted by 열ㅇl
Window/WPF2010. 2. 12. 20:34
 

이번 포스팅에서는

이미지 경로가 들어 있는 배열을 읽어 들어와

MouseEnter시 이미지 크기가 커지고 MouseLeave시 크기가 작아지는

간단한 애니메이션에 대해 알아 보겠습니다.

 

 

비하인드 코드에서 작성을 해보았습니다.

 

소스는 보시는 바와 같이

애니메이션을 만들어 이미지 객체의  EventTrigger에 연결 시키는 단순한 소스입니다.

   
    // 스토리 보드 생성

    Storyboard MenuReset = new Storyboard();

 

    DoubleAnimation withAnimation = new DoubleAnimation(100, new Duration(TimeSpan.Parse("0:0:0.15")));

    DoubleAnimation heightAnimation = new DoubleAnimation(150, new Duration(TimeSpan.Parse("0:0:0.15")));

 

    Storyboard.SetTargetProperty(withAnimation, new PropertyPath(WidthProperty));

    Storyboard.SetTargetProperty(heightAnimation, new PropertyPath(HeightProperty));

 

    MenuReset.Children.Add(withAnimation);

    MenuReset.Children.Add(heightAnimation);

 

    Storyboard ClickMenu = new Storyboard();

 

    DoubleAnimation _withAnimation = new DoubleAnimation(200, new Duration(TimeSpan.Parse("0:0:0.15")));

    DoubleAnimation _heightAnimation = new DoubleAnimation(300, new Duration(TimeSpan.Parse("0:0:0.15")));

 

    Storyboard.SetTargetProperty(_withAnimation, new PropertyPath(WidthProperty));

    Storyboard.SetTargetProperty(_heightAnimation, new PropertyPath(HeightProperty));

 

    ClickMenu.Children.Add(_withAnimation);

    ClickMenu.Children.Add(_heightAnimation);

 

    BeginStoryboard eventStoryboard1 = new BeginStoryboard();

    BeginStoryboard eventStoryboard2 = new BeginStoryboard();

 

    eventStoryboard1.Storyboard = ClickMenu;

    eventStoryboard2.Storyboard = MenuReset;

 

    // 이벤트 트리거

    EventTrigger eventTrigger = new EventTrigger(MouseEnterEvent);

    eventTrigger.Actions.Add(eventStoryboard1);

 

    EventTrigger eventTrigger2 = new EventTrigger(MouseLeaveEvent);

    eventTrigger2.Actions.Add(eventStoryboard2);

 

    foreach (string s in path)

    {

        Image image = new Image

        {

            Source = new BitmapImage(new Uri(s, UriKind.RelativeOrAbsolute)),

            Style = (Style)this.Resources["imageStyle"], // 스타일 적용

            Stretch = Stretch.Fill

        };

 

        // 이벤트 트리거 설정

        image.Triggers.Add(eventTrigger);

        image.Triggers.Add(eventTrigger2);

 

        stack.Children.Add(image);

    }

}

 

Posted by 열ㅇl
Window/WPF2010. 2. 11. 21:28

Canvas는 자식 객체들의 레이아웃에 영향을 주지 않으므로

자식 객체들은 항상 고정된 자신의 크기를 유지하게 됩니다.

 

그럼으로 Grid처럼 Image 객체의 Stretch속성 값을 Fill 로 설정을 해도

Canvas 크기 만큼 늘어나질 않죠.

 

이럴 경우 Image를 Canvas의 최하위 자식 요소, 즉 바탕화면으로 사용하려는

용도라면 Canvas의 Background로 지정하면 Canvas의 크기만큼 늘어나게 됩니다.

 

간단한 Xaml 코드는 다음과 같습니다.

 

<Canvas x:Name="canvas1"> 
   <Canvas.Background>
         <ImageBrush ImageSource="a.jpg"/>
   </Canvas.Background>

           .
           .
           .

 </Canvas>

'Window > WPF' 카테고리의 다른 글

[ WPF ] Page간 데이터 전달  (0) 2010.03.06
[ WPF ] 간단한 Image Animation  (2) 2010.02.12
[ WPF ] TextBox Select All Text  (0) 2010.02.11
[ WPF ] Window 사이즈 변경 시 컨트롤 크기 변경하기  (3) 2010.02.08
[WPF] Object Capture  (0) 2010.01.29
Posted by 열ㅇl
Window/WPF2010. 2. 11. 00:24

TextBox 사용 시 포커스가 왔을 때 다음과 같이

전체 내용을 선택해야 할 때가 있습니다.

 

 

 

 

 

 

 

 

 

 

 

 

여러 방법들이 있겠지만

간단하게 비하인드 코드에 작성된 이벤트 메서드를

여러 개의 TextBox의 GotFocus 이벤트와 연결하여 처리하는 방법에 대해 소개하겠습니다.

 

이벤트와 메서드를 연결합니다.

<TextBox GotFocus="TextBox_GotFocus" ... / >
<TextBox GotFocus="TextBox_GotFocus" ... / >

<TextBox GotFocus="TextBox_GotFocus" ... / >
<TextBox GotFocus="TextBox_GotFocus" ... / >

 

마우스로 클릭 후 포커스를 잃기 때문에 선택된 영역들이 다시 사라지게 됩니다.

이를 방지하기 위해 쓰레드를 사용하였습니다.

private void TextBox_GotFocus(object sender, RoutedEventArgs e)

{

    Dispatcher.CurrentDispatcher.BeginInvoke

    (

        DispatcherPriority.ContextIdle,

        new Action

        (

            delegate

            {

                (sender as TextBox).SelectAll();

            }

        )

    );                 

}

'Window > WPF' 카테고리의 다른 글

[ WPF ] 간단한 Image Animation  (2) 2010.02.12
[ WPF ] Canvas Image Background  (0) 2010.02.11
[ WPF ] Window 사이즈 변경 시 컨트롤 크기 변경하기  (3) 2010.02.08
[WPF] Object Capture  (0) 2010.01.29
[WPF] 시계 만들기  (0) 2010.01.26
Posted by 열ㅇl