참조 : http://blogs.msdn.com/llobo/archive/200 ··· ing.aspx

만약 여러분이 실버라이트에 익숙하다면 새로운 것은 없습니다. 이 속성 FrameworkElement에 새로이 추가가 되었었는데 각 길이를 반올림 하는 기능입니다. 기본 값은 실버라이트와 다르게 False이며 값을 설정하게 되면 자식 요소에 상속 됩니다. 이 속성을 설정한 것과 설정하지 않은 것은 다음과 같이 차이를 볼 수 있습니다.

사용자 삽입 이미지

예제 코드는 다음과 같습니다.

사용자 삽입 이미지

크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/12/30 17:25 2009/12/30 17:25
Posted by 나는산.
TAGS

Leave your greetings here.

[로그인][오픈아이디란?]
참조 : http://blogs.msdn.com/llobo/archive/200 ··· ogs.aspx

기존 OpenFileDialog나 SaveFileDialog가 XP 스타일 이였던 것을 Windows Vista/7 스타일로 수정되었습니다.

기존에는 다음과 같았으나,

사용자 삽입 이미지
다음과 같이 변경되었습니다.

사용자 삽입 이미지



크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/12/30 16:02 2009/12/30 16:02
Posted by 나는산.
TAGS

Leave your greetings here.

[로그인][오픈아이디란?]

참조 : http://blogs.msdn.com/llobo/archive/200 ··· ons.aspx

Easing 함수들은 여러분들의 애니메이션들에 사용자 정의 수학 방정식들을 추가할 수 있게 해줍니다. 이런 사용자 정의 수학 방정식들을 이용하면 애니매이션들은 더 실제와 같거나 부드럽습니다. WPF 4에서는 이런 사용자 정의 수학 방정식 11개가 미리 정의 되어 있습니다. 이들 각 함수들은 3개의 모드(EaseIn, EaseOut, EaseInOut)를 가집니다.

이번 WPF 4에서 기존에 있었거나 새롭게 추가된 애니매이션 관련 클래스들 - ByteAnimation, ColorAnimation, DecimalAnimation, DoubleAnimation, Int16Animation, Int32Animation, Int64Animation, Point3DAnimation, PointAnimation, QuaternionAnimation, RectAnimation, Rotation3DAnimation, SingleAnimation, SizeAnimation, ThicknessAnimation, Vector3DAnimation, VectorAnimation 등 - 전반적으로 EasingFunction 속성이 추가되었다. 이 속성은 IEasingFunction이라는 인터페이스로 정의 되어 있으며, 이것은 개발자에게 다양한 효과를 애니메이션에 적용할 수 있도록 만들수 있도록 해줍니다.

IEasingFunction에 대해서 더 자세하게 얘기하자면 0과 1사이의 정규화된 시간에 각각 값을 반환할 수 있는 함수를 만들 수 있도록 해준다. 쉽게 얘기하면 0은 애니메이션이 시작하는 값이고 1은 애니메이션이 끝나는 값을 가리킵니다.

WPF 4에서는 IEasingFunction을 상속받아 미리 정의해놓은 클래스가 11개가 있다고 했습니다. 이들은 클래스는 공통적으로 System.Windows.Media.Animation.EasingFunctionBase 클래스를 상속합니다. 대부분 미리 정의해 놓은 EasingFunction을 사용하지 않고 사용자가 직접 개발한다면 이 클래스를 상속 받아 사용합니다. EaseInCore 함수를 오버라이드 하여 작성하면 되는데 다음과 같이 하면 됩니다.

namespace CustomEasingFunction
{
    public class CustomSeventhPowerEasingFunction : EasingFunctionBase
    {
        public CustomSeventhPowerEasingFunction()
            : base()
        {
        }

        // Specify your own logic for the easing function by overriding

        // the EaseInCore method. Note that this logic applies to the "EaseIn"

        // mode of interpolation. 

        protected override double EaseInCore(double normalizedTime)
        {
            // applies the formula of time to the seventh power.

            return Math.Pow(normalizedTime, 7);
        }

        // Typical implementation of CreateInstanceCore

        protected override Freezable CreateInstanceCore()
        {

            return new CustomSeventhPowerEasingFunction();
        }

    }
}

EasingFunctionBase는 EasingMode 속성을 가지고 있습니다. EasingMode는 다음과 같이 3가지 모드가 있습니다.
- EaseIn : 기본 EaseInCore 구현대로 작동됩니다.
- EaseOut : 기본 EaseInCore와 반대로 작동됩니다. (X, Y좌표 -1 곱한값)
- EaseInOut : EaseIn 실행후 EaseOut 실행됩니다.

미리 정의해놓은 EasingFunction은 다음과 같습니다.

사용자 삽입 이미지

사용자 삽입 이미지

사용자 삽입 이미지

결론적으로 어떻게 보면 기존 Spline 사용하는 것을 더 넓게 적용, 더 자세하게 제어할 수 있게 되었다고 생각하면 될 것 같습니다.
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/12/30 15:40 2009/12/30 15:40
Posted by 나는산.
TAGS

Leave your greetings here.

[로그인][오픈아이디란?]

참조 : http://blogs.msdn.com/llobo/archive/200 ··· ush.aspx

WPF 4 부터는 TextBoxBase를 상속 받는 RichTextBox와 TextBox 컨트롤와 PasswordBox 컨트롤에 새로운 속성인 CaretBrush, SelectionBrush 그리고 SelectionOpacity가 추가되었다.

이전 버전에서는 텍스트 선택 색상과 투명도를 조절할 수 없었으며, 현재 커서 색상을 수정할 수 없었습니다. WPF4 부터는 텍스트 선택 부분을 개발자가 Brush로 설정하거나 텍스트 선택 부분의 투명도를 설정할 수 있습니다. 또, 현재 커서도 개발자가 Brush로 설정할 수 있습니다.

CaretBrush는 현재 커서의 표시를 Brush로 설정하거나 가져옵니다.
SelectionBrush는 현재 선택 부분의 표시를 Brush로 설정하거나 가져옵니다.
SelectionOpacity는 현재 선택 부분의 표시의 투명도를 설정하거나 가져옵니다.

사용자 삽입 이미지

크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/12/30 14:47 2009/12/30 14:47
Posted by 나는산.
TAGS

Leave your greetings here.

[로그인][오픈아이디란?]
When we want to declaratively use our custom controls or reference the types we defined in XAML, we should declare the XML namespace to map to the CLR namespace in which the controls and types are defined as the following XAML snippt demonstrates:

<Page x:Class="Test.MainWindow"
         xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
         xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:cc
="clr-namespace:Sheva.Windows.Controls;assembly=AvalonLib"
/>

    Recently, I am heavily engaged with writing a resuable WPF control library, and quite often I need to create some pages to test those controls I create, so ever now and then I have to use the cumbersome syntax like above to declare the XML namespace, personally I don't like the syntax, and I thought Microsoft WPF team should come up with a more elegant way of doing it, and in actuality, they did introduce an alternative to do it since the CTP releases. there is a custom attribute called XmlnsDefinitionAttribute in the System.Windows.Markup namespace which allows you to apply to the assembly which contains the types and controls the XAML code would reference.the built-in WPF assemblies such as WindowsBase.dll, PresentationCore.dll, and PresentationFramework.dll all have this attribute applied, and all have http://schemas.microsoft.com/winfx/2006/xaml/presentation namespace mapped with the CLR namespaces introduced by them. and of cause you can use this attribute in your own project, just open the AssemblyInfo.cs file, and append the following directive:

[assembly: XmlnsDefinition("http://schemas.sheva.com/wpf/", "Sheva.Windows.Controls")]

    Then you can declare the namespace alias in XAML this way:

<Page x:Class="Test.MainWindow"
         xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
         xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:cc
="http://schemas.sheva.com/wpf/"
/>
   
    Wow, this is a bit like the built-in xmlns declaration indeed, really really cool indeed:)
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/11/25 12:15 2009/11/25 12:15
Posted by 나는산.
TAGS

Leave your greetings here.

[로그인][오픈아이디란?]

IMAGE COLUMN

2009/10/04 13:48 / Etc
최근 9월달에 지인의 친구분과 함께 1년간의 프로젝트를 마쳤다.

회사 프로젝트가 아니라서 그리 집중해서 했지 않았던것이 후회라면 후회이지만,

지인의 친구분은 흡족했었다.

인사동의 한 갤러리에서 나의 손길이 들어간 작품을 보니 흐믓했다.

사용자 삽입 이미지


예술과 컴퓨터 프로그래밍의 만남은 언제나 봐도 신기하다.

사용자 삽입 이미지
사용자 삽입 이미지

C#의 WPF 기술과 OpenCV의 기술을 이용해서 사람 얼굴을 인식하여 사진에 합성하는 프로그램을 만들었다.

WPF의 쉬운 프로그래밍은 정말 나에게 큰도움을 줬다.

만약 MFC로 시작했다면 못했을지도 모른다...
크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/10/04 13:48 2009/10/04 13:48
Posted by 나는산.
TAGS ,

Leave your greetings here.

[로그인][오픈아이디란?]


흔히 WPF를 사용하다보면, WinForm에 있는 System.Drawing.Bitmap을 가져와 사용할때가 있는다.

그래서 흔시 Googling을 하다보면 다음 코드를 사용하게 된다.

        public static BitmapSource ConvertToBitmapSource(System.Drawing.Bitmap source)

        {

            var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(

                source.GetHbitmap(),

                IntPtr.Zero,

                Int32Rect.Empty,

                BitmapSizeOptions.FromEmptyOptions());

            bitmapSource.Freeze();


            return bitmapSource;

        }



그런데 이 코드는 메모리 문제가 있는다. 계속 호출하면 메모리가 증가한다.

ㅠ.ㅠ

다시 자세히 검사해보면 다음 코드를 발견할 수 있다.

        private static BitmapSource CreateBitmapSource(Bitmap bitmap)

        {

            Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);

            BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);


            BitmapSource source = BitmapSource.Create(bitmap.Width, bitmap.Height,

                bitmap.HorizontalResolution, bitmap.VerticalResolution, PixelFormats.Pbgra32, null,

                bitmapData.Scan0, bitmapData.Stride * bitmap.Height, bitmapData.Stride);


            bitmap.UnlockBits(bitmapData);


            return source;

        }



일단 많이 호출해도 메모리가 증가하지 않는다.

그럼 위에 코드는 뭐가 잘못 되었을까?


source.GetHbitmap() 부분이 문제라고 한다.


핸들을 갔다가 사용했으면 반환해야 한다.


다음과 같이 수정하면 메모리 증가가 없다.

        private static readonly List<IntPtr> _bitmapsToDelete = new List<IntPtr>();


        [DllImport("gdi32.dll")]

        private static extern bool DeleteObject(IntPtr hObject);


        private static void DeleteBitmaps()

        {

            foreach (IntPtr bitmap in _bitmapsToDelete)

            {

                DeleteObject(bitmap);

            }

            GC.Collect(0, GCCollectionMode.Forced);

        }


        public static BitmapSource ConvertToBitmapSource(System.Drawing.Bitmap source)

        {

            DeleteBitmaps();


            IntPtr handle = source.GetHbitmap();

            _bitmapsToDelete.Add(handle);


            var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(

                handle,

                IntPtr.Zero,

                Int32Rect.Empty,

                BitmapSizeOptions.FromEmptyOptions());

            bitmapSource.Freeze();


            return bitmapSource;

        }


필자는 전자 방법이 문제가 없었다.

두번째 방법은 UI 쓰레드 때문에 조금 손봤어야 했다.

크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/08/31 23:05 2009/08/31 23:05
Posted by 나는산.
TAGS

Leave your greetings here.

[로그인][오픈아이디란?]

public static IEnumerable<T> Traverse<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> fnRecurse)
        {
            foreach (T item in source)
            {
                yield return item;

                IEnumerable<T> seqRecurse = fnRecurse(item);

                if (seqRecurse != null)
                {
                    foreach (T itemRecurse in Traverse(seqRecurse, fnRecurse))
                    {
                        yield return itemRecurse;
                    }
                }
            }
        }

크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/07/01 01:27 2009/07/01 01:27
Posted by 나는산.
TAGS ,

Leave your greetings here.

[로그인][오픈아이디란?]
참조 : http://thibaud60.blogspot.com/2009/02/c ··· ith.html

WPF에서 Model/ModelView/View 패턴 사용시 어려운 점 한가지는 명령을 바인딩 하는 것이다. 우리가 간단한 함수를 ModelView에 선언해서 바인딩하려면 쉽지는 않다.

참부된 소스의 MethodBinding 접근은 이런 어려운 일들을 대신해준다.

사용자 삽입 이미지


크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/04/27 14:22 2009/04/27 14:22
Posted by 나는산.
TAGS

Leave your greetings here.

[로그인][오픈아이디란?]
 

WPF Multithreaded UI

 

 

참조 사이트: http://blogs.msdn.com/dwayneneed/archiv ··· ual.aspx

 

WPF Threading Model

일반적으로, WPF에 있는 객체들은 오직 자신을 생성한 Thread로 부터 접근이 가능하다. 때때로, UI Thread의 제한은 헛갈리지만, 사실 객체가 다른 Thread에 사는 것은 완벽히 좋다. 하지만 일반적으로 하나의 Thread에 객체를 생성하고 다른 Thread에서 접근하는 것은 불가능 하다. 대부분 이런 상황에서는 “The calling thread cannot access this object because a different thread owns it.”라는 메시지로 시작하는 InvalidOperationException이 발생한다.

 

Freezables

당연히 UI Thread의 제한에 대해 예외가 존재한다. 잘 알려진 객체는 Freezable 클래스이다. Freezable 객체들은 어떤 특정 상황에서 읽기 전용이 되어서 Single-Thread 제한에서 벗어날 수 있다. 이 상황을 “frozen”이라고 하자. “frozen” Freezable 객체들은 대표적으로 Brushes 클래스에서 가능한 표준 Brush들을 예로 들 수 있다. 이들 Brush들은 아무 시간이나 Thread로 부터 사용될 수 있다.

 

Separate Windows

불행하게도 읽기 전용 제한은 엄청난 문제가 있다. UI 분리된 부분들을 분리된 Thread에서 실행하고 싶은 많은 시나리오들이 존재한다. 만약 이들 UI 부분들이 서로 독립적이라면, 여러분은 이들은 다른 윈도우에 호스트 하여, 윈도우들을 분리된 Thread 실행하면 된다.  이것은 어떤 시나리오들에 있어서 의미 있는 해결책이 있다. 특히, 독립적인 최상위 윈도우들에서 분리된 Thread들이 실행될 있는 시나리오에 적합하다. 접근에 대한 제한은 윈도우부터의 그래픽스들이 다른 윈도우의 그래픽스와 혼합될 없다. 따라서, 다른 Thread UI 자식 윈도우를 사용하는 동안에는 시스템은 그냥 다른 객체 위에 객체를 그리게 된다. 여러분은 Transparency 사용할 없으며, 다른 객체를 Brush 사용할 없으며, 다른 객체 위에 그릴 없다.

 

HostVisual

만약 여러분의 시나리오가 상호작용(사용자 입력)이 요구되지 않는다면, WPF에는 HotVisual이라는 옵션을 제공해주고 있다. 이 옵션은 WPF에 강력한 Composition 엔진을 가동해 준다.  이 구성 엔진은 다중 Thread부터의 그려지는 Primitive들을 하나의 화면에 결집하는 것이 이미 가능하다. Worker Thread에 의해 소유된 Element Tree는 자신 안에 자신만의 Composition Target(VisualTarget이라고 함)에 그려져서 결과는 UI Thread에게 소유된 HostVisual에 합쳐진다.

 

Issue #1: Hosting a Visual in XAML

해결 해야 할 첫 번째 문제는 HostVisual Visual로 부터 상속 받는다. Visual을 호스트하기 위해서는 Panel이나 Border를 사용할 수 없다. Border는 하나의 자식을 가진 Panel들을 위한 표준 Base 클래스인 Decorator로 부터 상속 받는다. 불행하게도, Decorator의 자식은 강력하게 UIElement로 제한한다. 우리는 UIElement로부터 상속 받지 않은 HostVisual 사용해야 한다. 더 나아가 표준 요소들(Border, Grid, Canvas )의 자식으로 Visual으로 설정할 방법이 없기 때문에 직접 만들어야 한다.

[ContentProperty("Child")]

    public class VisualWrapper : FrameworkElement

    {

        public Visual Child

        {

            get

            {

                return _child;

            }

 

            set

            {

                if (_child != null)

                {

                    RemoveVisualChild(_child);

                }

 

                _child = value;

 

                if (_child != null)

                {

                    AddVisualChild(_child);

                }

            }

        }

 

        protected override Visual GetVisualChild(int index)

        {

            if (_child != null && index == 0)

            {

                return _child;

            }

            else

            {

                throw new ArgumentOutOfRangeException("index");

            }

        }

 

        protected override int VisualChildrenCount

        {

            get

            {

                return _child != null ? 1 : 0;

            }

        }

 

        private Visual _child;

    }

 

Issue #2: Layout and the Loaded event

WPF는 매우 편리한 “Loaded”라는 이벤트를 제공한다. 이 이벤트는 기본적으로 요소가 완벽히 Initialized, Measured, Arranged, Rendered 그리고 윈도우 같은 Presentation Source에 들어간 후를 알려준다. MediaElement을 포함한 많은 요소들이 이 이벤트들을 이용하지만, 슬프게도 이 이벤트는 Presentation Source에 들어가지 않은 Element Tree를 위해 호출 되지 않아서, HostVisual/VisualTarget을 통한 Element Tree 표시는 당연히 Loaded 이벤트가 호출되지 않는다. 따라서 우리는 우리 자신만의 Presentation Source를 만들어서 Worker Thread이 소유할 최상위 Element Tree로 사용할 것이다. 이것은 즉시 다른 문제로 발전한다. Layout Presentation Source에 의해 다시 명령되지 않으면 모든 요소들에 의해 멈춘다. 불행하게도 이것을 하기 위한 공식적인 메커니즘은 internal로 되어 있기 때문에, 최상의 방법은 명시적으로 최상위 요소를 measure arrange하는 것이다.

public class VisualTargetPresentationSource : PresentationSource

    {

        public VisualTargetPresentationSource(HostVisual hostVisual)

        {

            _visualTarget = new VisualTarget(hostVisual);

        }

 

        public override Visual RootVisual

        {

            get

            {

                return _visualTarget.RootVisual;

            }

 

            set

            {

                Visual oldRoot = _visualTarget.RootVisual;

 

                // Set the root visual of the VisualTarget.  This visual will

                // now be used to visually compose the scene.

                _visualTarget.RootVisual = value;

 

                // Tell the PresentationSource that the root visual has

                // changed.  This kicks off a bunch of stuff like the

                // Loaded event.

                RootChanged(oldRoot, value);

 

                // Kickoff layout...

                UIElement rootElement = value as UIElement;

                if (rootElement != null)

                {

                    rootElement.Measure(new Size(Double.PositiveInfinity,

                                                 Double.PositiveInfinity));

                    rootElement.Arrange(new Rect(rootElement.DesiredSize));

                }

            }

        }

 

        protected override CompositionTarget GetCompositionTargetCore()

        {

            return _visualTarget;

        }

 

        public override bool IsDisposed

        {

            get

            {

                // We don't support disposing this object.

                return false;

            }

        }

 

        private VisualTarget _visualTarget;

    }

 

Background Threads

C#에서는 Thread들을 만들기 쉽다. 다만 하나 주위 해야 할 것은 Thread“Background” Thread로 선언해야 한다. “Background” Thread로 선언하지 않으면 응용프로그램은 Thread가 살아 있을 때까지 계속 실행이 될 것이다. 또한 기억할 것은 WPF의 부분들은 COM“Single Threaded Apartment”로 선언되어야 한다.

Thread thread = new Thread(/*…*/);

thread.ApartmentState = ApartmentState.STA;

thread.IsBackground = true;
thread.Start(/*…*/);

 

The Demo

XAML

<Window x:Class="VisualTargetDemo.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:local="clr-namespace:VisualTargetDemo"

    Title="VisualTargetDemo"

    SizeToContent="WidthAndHeight"

    Loaded="OnLoaded"

    >

  <Grid>

    <Grid.ColumnDefinitions>

      <ColumnDefinition Width="*"/>

      <ColumnDefinition Width="*"/>

      <ColumnDefinition Width="*"/>

    </Grid.ColumnDefinitions>

    <local:VisualWrapper Grid.Column="0"

                         Width="200" Height="100" x:Name="Player1"/>

    <local:VisualWrapper Grid.Column="1"

                         Width="200" Height="100" x:Name="Player2"/>

    <local:VisualWrapper Grid.Column="2"

                         Width="200" Height="100" x:Name="Player3"/>

  </Grid>

</Window>

 

Code

public partial class Window1 : System.Windows.Window

    {

        public Window1()

        {

            InitializeComponent();

        }

 

        private void OnLoaded(object sender, RoutedEventArgs e)

        {

            Player1.Child = CreateMediaElementOnWorkerThread();

            Player2.Child = CreateMediaElementOnWorkerThread();

            Player3.Child = CreateMediaElementOnWorkerThread();

        }

 

        private HostVisual CreateMediaElementOnWorkerThread()

        {

            // Create the HostVisual that will "contain" the VisualTarget

            // on the worker thread.

            HostVisual hostVisual = new HostVisual();

 

            // Spin up a worker thread, and pass it the HostVisual that it

            // should be part of.

            Thread thread = new Thread(new ParameterizedThreadStart(MediaWorkerThread));

            thread.ApartmentState = ApartmentState.STA;

            thread.IsBackground = true;

            thread.Start(hostVisual);

 

            // Wait for the worker thread to spin up and create the VisualTarget.

            s_event.WaitOne();

 

            return hostVisual;

        }

 

        private FrameworkElement CreateMediaElement()

        {

            // Create a MediaElement, and give it some video content.

            MediaElement mediaElement = new MediaElement();

            mediaElement.BeginInit();

            mediaElement.Source = new Uri("http://download.microsoft.com/download/2/C/4/2C433161-F56C-4BAB-BBC5-B8C6F240AFCC/SL_0410_448x256_300kb_2passCBR.wmv?amp;clcid=0x409");

            mediaElement.Width = 200;

            mediaElement.Height = 100;

            mediaElement.EndInit();

 

            return mediaElement;

        }

 

        private void MediaWorkerThread(object arg)

        {

            // Create the VisualTargetPresentationSource and then signal the

            // calling thread, so that it can continue without waiting for us.

            HostVisual hostVisual = (HostVisual)arg;

            VisualTargetPresentationSource visualTargetPS = new VisualTargetPresentationSource(hostVisual);

            s_event.Set();

 

            // Create a MediaElement and use it as the root visual for the

            // VisualTarget.

            visualTargetPS.RootVisual = CreateMediaElement();

 

            // Run a dispatcher for this worker thread.  This is the central

            // processing loop for WPF.

            System.Windows.Threading.Dispatcher.Run();

        }

 

        private static AutoResetEvent s_event = new AutoResetEvent(false);

    }

 

 

 

 

크리에이티브 커먼즈 라이센스
Creative Commons License
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/04/17 17:07 2009/04/17 17:07
Posted by 나는산.

Leave your greetings here.

[로그인][오픈아이디란?]
« Previous : 1 : 2 : 3 : 4 : 5 : Next »