2010년 12월 10일 금요일

Application의 MainWindow, Startup, ShutdownMode 프로퍼티




  Visual Studio의 WPF 응용프로그램 템플릿으로 프로젝트를 생성하면  App.xaml 과 MainWindow.xaml 파일이 생성된다.






App.xaml 파일의 Build Action 프로퍼티값이 ApplicationDefinition으로 설정되어 있기 때문에 WPF는 빌드 작업을 통해 App.xaml 의 클래스가 응용프로그램 클래스인 지 알아내고, Main() 함수를 생성하고 App의 클래스 인스턴스를 생성하며 Run()메소드를 호출한다. 일반적으로 반복되는 작업이므로 템플릿으로 자동으로 코드가 추가되는 것이다. 



 이 상태에서 빌드 및 실행하면 MainWindow가 출력이 되는데, 내가 원하는 것은 MainWindow가 출력되기 전에 다른 윈도우를 출력 시키고, 해당 윈도우의 리턴값에 따라 응용프로그램이 종료되거나 MainWindow를 출력시키는 것이다. 

 WinForm에서는 Program.cs 파일에서 이런 작업을 해주었는데 WPF에서는 어디서 해줘야 할까??



 WPF가 자동으로 Main()함수를 만들고, Application 인스턴스를 만든다. 또한 Application 인스턴스의  Run() 메소드를 실행 시킨다. Run() 메소드를 실행 시키면 Startup 이벤트가 발생하며 OnStartup 이벤트 핸들러가 호출되게 된다. 따라서 OnStartup 이벤트 핸들러에서 메인 윈도우를 출력하게 된다. 그래!! 그렇다면 여기서 MainWindow 호출 전에 처리할 작업을 작성하면 되는 것이다.








StartupUri 어트리뷰트를 지우고, Startup 어트리뷰트를 지정한다. 즉, Startup 이벤트의 이벤트 핸들러를 등록한다.








Startup 이벤트 핸들러에서 원하는 작업을 넣어주면 된다. MainWindow 를 사용하기 전에 WndDbLogin 윈도우를 먼저 사용하였으며 그 리턴값에 따라 MainWindow의 출력 유무가 결정된다.





Remarks



몇가지 주의해야 할 점이 있다. 



Application 응용프로그램 인스턴스는 제일 처음으로 생성되는  윈도우를 MainWindow 프로퍼티에 설정한다. 

즉, 최상위 윈도우로 설정하게 되는데 위 코드에서 WndDbLogin 을 먼저 생성하게 되면 이 윈도우가 MainWindow가 되므로 최상위 윈도우로 사용할 윈도우를 먼저 생성 및 MainWindow 프로퍼티에 설정해주다.



 응용프로그램은 보통 하나의 주 윈도우를 사용하며 주 윈도우가 종료되면 응용프로그램도 종료되게 된다. 

응용프로그램의 종료 모드는 ShutdownMode 프로퍼티를 통해 설정할 수 있으며 기본값으로는 OnLastWindowClose 열거값으로 설정되어 있다. 이 값을 OnMainWindowClose 열거값으로 설정해주자.

2010년 12월 3일 금요일

Business Form 을 위한 WPF StackPanel 의 사용




 Business logic 을 담은 Business Form WPF 응용프로그램에서 Layout 을 Grid 컨트롤로 많이 작성하게 된다. Grid 컨트롤은 매우 유연하여 많이 사용되어 지는데, 언제나 그렇듯 모든 곳에서 Grid가 적절한 것은 아니다. 

다음 블로그의 글을 참조하세요!!











요약하자면!!

Business Form 을 위한 Layout에서 StackPanel과 Grid의 사용은 각각 장점과 단점이 있다.



Grid 의 장점과 단점

- 유연한 Layout 구현

- Business Form 의 크기 변경 시, 내부 엘리먼트도 자동으로 re-sizing 된다. 특히 TextBox를 사용할 때 유용

- Grid는 row와 column에 번호를 매겨서 관리되기 때문에 기존 row/column 을 조작한다거나, 새로운 row/column을

   추가할 때 번호를 손 수 매겨야 하는 번거러움이 있다.



StackPanel 의 장점과 단점

- Grid만큼 유연하지 않지만(원래 StackPanel은 작게 구분된 영역을 정렬하는데 유용하다.)  Style을 설정함으로써 Grid와

  비슷한 유연함을 가질 수 있다.

- 기존 UI 엘리먼트의 변경, 새로운 엘리먼트 추가 시 번호를 매기는 번거로움이 없다.





Business Form 에서 re-sizing을 유념해야 한다면 Grid가 적절하지만, 고정된 크기를 갖는 Business Form 에서는 StackPanel 역시 유용할 수 있는 내용이다.



어차피 어떤것을 구현함에 있어 방법은 많다. 이렇게도 해보고, 저렇게도 해보고, 이렇게 하면 이게 좋고, 저렇게 하면 저게 나쁘구나.. 이런 많은 경험이 있어야 되겠다.













2010년 12월 2일 목요일

Creating Border-less Windows in WPF











Border-less Windows 즉, 윈도우 창에 테두리가 없는 윈도우를 말한다. WPF 에서 스플래쉬 윈도우나, 일반적이지 않은 특별한 윈도우를 만들기 위해서는 border 가 없는 윈도우에 작업을 한다. 비단 WPF 뿐만이 아니라 MFC, WinForm 에서도 이런 방식을 사용하고 있다. 






Figure 1 : border 를 갖지 않는 윈도우






Setting Window Attributes



Border가 없는 윈도우를 만들기 위해서는 window의 다음 어트리뷰트를 설정해주어야 한다.



● WindowStyle="None"

● ShowInTaskBar="False"

● AllowsTransparency="True"

● Background="Transparent"



WindowStyle, ShowInTaskBar 어트리뷰트 WinForm 에서도 사용되어지니 눈에 익숙하다. 실제로 border를 없애는 것은 WindowStyle 어트리뷰트이며 ShowInTaskBar는 선택적인 옵션이다. AllowTransparency 과 Background 어트리뷰트가 중요하다. 이 두 어트리뷰트는 함께 설정해야 하며, Background를 Transparent로 설정하기 위해선 AllowTransparency를 True로 설정해야 한다. 이 두 어트리뷰트를 설정하지 않으면 border가 계속 보이게 된다.






Figure 2 : WindowStyle="None", AllowTransparency 와 Background 는 설정하지 않은 경우





예제 XAML 코드



<Window x:Class="NoBorderDemo.MainWindow"

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

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

        Title="MainWindow" 

        Height="350" Width="525"

        WindowStyle="None" AllowsTransparency="True" Background="Transparent"

        ResizeMode="NoResize"

        ShowInTaskbar="False"

        WindowStartupLocation="CenterScreen">

    <Border BorderBrush="Gray"

            BorderThickness="0, 0, 2, 2"

            CornerRadius="10"

            Background="Beige">

        <Border BorderBrush="Transparent"

                BorderThickness="5"

                CornerRadius="10">

            <Border BorderBrush="Black"

                    BorderThickness="1.5"

                    CornerRadius="10">

                <StackPanel Background="Yellow"

                            VerticalAlignment="Bottom"

                            HorizontalAlignment="Center"

                            Margin="10">

                    <Button Click="Button_Click">

                        Close Me

                    </Button>                    

                </StackPanel>

            </Border>        

        </Border>

    </Border>

</Window>