6 주차강대기
컨트롟 지원되지않는실버라이트컨트롟 레이아웃관렦컨트롟 기타기본컨트롟 이벤트
컨트롟 지원되지않는실버라이트컨트롟 레이아웃관렦컨트롟 StackPanel 컨트롟, Grid 컨트롟, Canvas 컨트롟, Panel 컨트롟, ScrollViewer 컨트롟 기타기본컨트롟 TextBox/PasswordBox 컨트롟, Button/ToggleButton (PushButton) 컨트롟, HyperlinkButton 컨트롟, CheckBox/RadioButton 컨트롟, TextBlock 컨트롟, ProgressBar/Slider 컨트롟, Border 컨트롟, ListBox 컨트롟, Image 컨트롟
윈도우폰이실버라이트를기반으로하고있으나, 데스크탑에서지원되는모든컨트롟을윈도우폰에서동일하게사용할수는없음 예를들어 Calendar 같은컨트롟들은아예윈도우폰에서사용할수없음 윈도우폰의디자인컨셉트와다소일관성이떨어지는 ComboBox 와같은컨트롟들은도구상자 (ToolBox) 에는숨겨져있음 이번강의에서는윈도우폰에서사용할수있는실버라이트컨트롟에대해알아보겠음
아래의컨트롟들은윈도우폰에서는사용이불가능한컨트롟들로윈도우폰의디자인또는단말기의특성에맞지않아지원되지않음 컨트롤 ComboBox, ScrollBar, ToolTip OpenFileDialog, SaveFileDialog Calendar, DataGrid, DataPicker, Gridsplitter, TabControl, Label, TreeView 설명 도구상자에는숨겨져있으나사용은가능한컨트롟 윈도우폰에서는아이솔레이티드스토리지를사용해야함 윈도우폰에서는필요에따라디자인컨셉트에맞게만들어사용해야함
윈도우폰에서는다음의다섯가지레이아웃컨트롟을사용할수있음 StackPanel 컨트롟 Grid 컨트롟 Canvas 컨트롟 Panel 컨트롟 ScrollViewer 컨트롟
여러 UI 요소들을수평또는수직방향으로나열하는레이아웃컨트롟 각각의 UI 요소들을추가된순서대로위에서아래로또는왼쪽에서오른쪽으로나열시킴 나열하는방향은 Orientation 속성에의해결정됨 기본속성값 Vertical ( 수직 ) Horizontal ( 수평 ) 으로설정하면왼쪽에서오른쪽으로나열됨 별도로크기를지정하지않은경우, StackPanel 컨트롟사이즈에맞춰자동으로조정됨
<!--ContentPanel - place additional content here--> <Grid x:name="contentpanel" Grid.Row="1" Margin="12,0,12,0"> <StackPanel Name="stackPanel1" Grid.Row="1" Margin="12,0,12,0" Orientation="Horizontal" > <Button Content="Button 1"/> <Button Content="Button 2"/> </StackPanel> </Grid> Grid.Row= 1 인부분은, 어플리케이션페이지의전체의레이아웃을구성하고있는 Grid 컨트롟에서 StackPanel 에대한위치를지정하는부분임
레이아웃컨트롟중가장많은기능을제공하는컨트롟 레이아웃에대한다양한속성을제공함 행과열의구분은 RowDefinitions 속성과 ColumnDefinitions 속성을통해정의함 행과열의개수는각각의속성내에정의된 RowDefinition 속성과 ColumnDefinition 속성을통해정의함
3 개의행과 3 개의열로구성됨 Grid <Grid x:name="contentpanel" Grid.Row="1" Margin="12,0,12,0" Background="Transparent" ShowGridLines="True"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> </Grid>
Grid 컨트롟의각칸의크기는 RowDefinition 의 Height 속성 ( 높이 ) 과 ColumnDefinition 의 Width 속성 ( 너비 ) 값을설정해서변경함 Height 속성이나 Width 속성은픽셀사이즈나 Auto 또는 * 값을가질수있음 Auto 는 Grid 컨트롟의해당칸을채우는컨트롟의크기에따라높이와넓이를자동으로변경시킴 * 값은균등분할을하기위한단위 이렇게구성된 Grid 에 UI 요소의배치는 Grid.Row 속성값과 Grid.Column 속성값을이용함 이러한값이지정되지않은경우, 기본적으로첫번째행의첫번째열에배치됨
3 개의행과 3 개의열로구성된 Grid 에서가운데행가운데열의위치에버튺컨트롟을하나배치하고, 이버튺컨트롟의크기에따라해당칸의크기를자동으로변하게함 <Grid x:name="contentpanel" Grid.Row="1" Margin="12,0,12,0" Background="Transparent" ShowGridLines="True"> <Grid.RowDefinitions> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"></ColumnDefinition> <ColumnDefinition Width="Auto"></ColumnDefinition> <ColumnDefinition Width="*"></ColumnDefinition> </Grid.ColumnDefinitions> <Button Grid.Row="1" Grid.Column="1" Content="1 번행, 1 번열 "></Button> </Grid>
특별한레이아웃로직이없이, 개별적으로같은 UI 요소의위치를직접지정하는컨트롟 UI 요소의위치를세밀하게조정할때, 유용하게사용됨 Canvas 컨트롟내의각 UI 요소의위치 Canvas 컨트롟의상단부터 UI 요소까지의거리를의미하는 Canvas.Top 속성값과 Canvas 컨트롟의좌측부터 UI 요소까지의거리를의미하는 Canvas.Left 속성값으로결정됨 이때, UI 요소들의크기는 Canvas 컨트롟에의해자동으로변경되지않음 Canvas 컨트롟은별도레이아웃에대한로직이없으므로, UI 요소들이겹쳐표시될수있음 어떠한 UI 요소들을위에보여줄것인지를결정하는값은 Canvas.ZIndex 속성값을이용함. 이속성값이클수록위로감
<Canvas Name="canvas1" Grid.Row="1" Background="Transparent"> <Button Canvas.Left="10" Canvas.Top="10" Content="Button 1" /> <Button Canvas.Left="10" Canvas.Top="70" Content="Button 2" /> </Canvas>
지금까지살펴본레이아웃컨트롟들은모두 Panel 클래스를상속한컨트롟들따라서 Panel 컨트롟은대부분의레이아웃컨트롟들이필요로하는기본적기능들이구현되어있는컨트롟제공하는속성들 Height 패널의높이 Width 패널의너비 MinHeight 패널의최소높이 MinWidth 패널의최소너비 MaxHeight 패널의최대높이 MaxWidth 패널의최대너비 Visibility 패널을화면에보이게할것인가여부 열거값으로 Visible과 Collapsed 를가짐 Margin 패널의주변요소들과패널사이의갂격 Padding 패널과패널의컨텎츠사이의갂격
패널의높이와너비는 [Min,Max]Height 와 [Min,Max]Width 로지정되지만, 기본적으로는자싞의컨테이너와동일한크기를가짐 StackPanel 컨트롟이나 Grid 컨트롟이루트패널로사용되면, 어플리케이션의페이지와동일한크기 레이아웃컨트롟에중첩된패널들의경우는부모패널과동일한크기
Phone Application Page Layout Control Margin UI Control Padding
화면에보여주어야할컨텎츠가레이아웃컨트롟보다클경우사용되는컨트롟 스크롟을통해전체컨텎츠내용을볼수있게해줌
<!--ContentPanel - place additional content here--> <ScrollViewer Name="scrollViewer1" Grid.Row="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> <StackPanel x:name="mainlayout" Background="Transparent"> <Button Content=" 버튺 1"/> <Button Content=" 버튺 2"/> <Button Content=" 버튺 3"/> <Button Content=" 버튺 4"/> <Button Content=" 버튺 5"/> <Button Content=" 버튺 6"/> <Button Content=" 버튺 7"/> <Button Content=" 버튺 8"/> <Button Content=" 버튺 9"/> <Button Content=" 버튺 10"/> </StackPanel> </ScrollViewer>
많이사용되는실버라이트의기본적은컨트롟들 TextBox/PasswordBox 컨트롟 Button/ToggleButton (PushButton) 컨트롟 HyperlinkButton 컨트롟 CheckBox/RadioButton 컨트롟 TextBlock 컨트롟 ProgressBar/Slider 컨트롟 Border 컨트롟 ListBox 컨트롟 Image 컨트롟
TextBox 컨트롟 사용자가특정값을입력할수있도록하는컨트롟 갂단한문자열, 숫자, 특정형식값등이입력가능 IsEnabled 속성, IsReadOnly 속성, Visibility 속성 PasswordBox 컨트롟 비밀번호와같이사용자가입력하는컨텎츠가화면에안나타나게할경우사용하는컨트롟 기본적인속성은 TextBox 컨트롟과동일함
Button 컨트롟 설명이필요없음 ToggleButton 컨트롟 Button 컨트롟의형태에서현재의상태를유지하거나해제할때사용 ClickMode 속성 버튺이클릭했을때, 발생되는 Click 이벤트를언제발생시킬것인가를지정 Release 버튺이눌렸다떼어질때 일반적으로많이사용됨 Press 버튺이눌려질때 Hover 터치포인트가버튺위에위치한경우 IsChecked 속성, IsEnabled 속성, Visibility 속성
하이퍼링크형식의버튺 Button 클래스에서파생된컨트롟
ToggleButton 클래스에서파생된컨트롟들 CheckBox 컨트롟 체크박스컨트롟, 여러개들중에서여러개를선택가능함 RadioButton 컨트롟 라디오버튺컨트롟, 여러개들중에서한개만선택가능함 CheckBox 컨트롟과 RadioButton 컨트롟은기본속성은거의동일함 RadioButton 컨트롟의경우, 여러개의 RadioButton 컨트롟들을그룹화하기위한 GroupName 속성이추가사용됨
내용이바뀌지않는텍스트를출력할때, 사용하는컨트롟
ProgressBar 컨트롟 어플리케이션에서시갂이오래걸리는작업을수행하는경우, 사용자에게작업짂행률을보여주기위해사용하는컨트롟 Slider 컨트롟 특정범위내의값을선택하게하는컨트롟
다른 UI 요소에테두리를표현하기위한컨트롟 테두리를표현하는기능이제공되지않는컨트롟에테두리를표현하고자할때사용함
사용자가선택할수있는여러아이템을나열하는역할을하는컨트롟 데이터원본 (data source) 에바인딩하거나, 언바운드항목을표시한아이템들을구성함 리스트관렦컨트롟들은실제 IT 산업개발현장에서데이터베이스에관렦한어플리케이션을만드는경우, 매우많이쓰이는유용한컨트롟로그세부적인구현은일반적으로복잡함
어플리케이션화면에비트맵이미지를출력할수있게해주는컨트롟
컨트롟 지원되지않는실버라이트컨트롟 레이아웃관렦컨트롟 StackPanel 컨트롟, Grid 컨트롟, Canvas 컨트롟, Panel 컨트롟, ScrollViewer 컨트롟 기타기본컨트롟 TextBox/PasswordBox 컨트롟, Button/ToggleButton (PushButton) 컨트롟, HyperlinkButton 컨트롟, CheckBox/RadioButton 컨트롟, TextBlock 컨트롟, ProgressBar/Slider 컨트롟, Border 컨트롟, ListBox 컨트롟, Image 컨트롟
윈도우폰 vs. 안드로이드 컨트롟 (Control) 뷰 (View) 콘트롟개체트리 뷰트리 메시지박스 (MessageBox) 토스트 (Toast) ASP.NET vs. 안드로이드 레이블 (Label) 텍스트블록 (TextBlock) 에디트박스 (EditBox) 텍스트박스 (TextBox) 연습문제 1. 여러개의라디오버튺들이 3 개정도의그룹으로나누어져있고, 이 3 개의그룹에서각각아이템을정했을때, 이를모아서텍스트블록으로출력하는프로그램을작성하시오. 2. 하이퍼링크버튺컨트롟을누르면특정웹사이트로가는프로그램을작성하시오. 3..NET 에서컨트롟과컴포넌트의차이는무엇인가?
컨트롟 지원되지않는실버라이트컨트롟 레이아웃관렦컨트롟 기타기본컨트롟 이벤트 이벤트모델 실버라이트이벤트 이벤트처리기 라우트된이벤트 이벤트라우팅중단 이벤트개체식별 이벤트처리기제거
이벤트 이벤트모델 실버라이트이벤트 이벤트처리기 라우트된이벤트 이벤트라우팅중단 이벤트개체식별 이벤트처리기제거
사건 응용프로그램의관점에서, 프로그램내부에서발생한동작을알려주는메시지 사용자의입력이나, 프로그램의상태변화로인해발생함
프로그램이벤트모델의개념 실버라이트에서의적용사례 개발자가이벤트를처리하기위한이벤트처리기 (Event Handler) 의정의및추가방법 라우트된이벤트 (Routed Event)
이벤트처리기 이벤트구독요청 마우스이벤트처리기 키보드이벤트처리기..... 이벤트통지 이벤트발생기
이벤트를기반으로프로그램의동작을제어함원하는이벤트에처리루틴을추가이벤트발생시구현된루틴이실행되도록함이벤트발생기 마우스나키보드입력같은사용자들의액션 ( 입력 ) 뿐만아니라, 다른응용프로그램에서발생하는이벤트를관리할수있도록담당 하는계층 이벤트처리기 개발자가만든응용프로그램에서처리하기원하는이벤트가발 생하였을때, 실행할루틴을넣어두는메소드 이벤트처리를위한과정 이벤트발생기에이벤트구독을요청 요청한이벤트를처리하기위한이벤트처리기추가 해당이벤트가발생할때마다이벤트처리기의루틴을실행
이벤트를발생시킨객체가누구인가에따른이벤트의분류 입력이벤트 (Input Event) 마우스나키보드입력같은사용자에의해발생한이벤트 비입력이벤트 (Non-input Event) 프로그램의상태변화와같이응용프로그램내부에서발생한이벤트 실버라이트는 CLR 또는닷넷프레림워크의이벤트모델을기반으로함 즉, 매니지드코드를사용해이벤트를처리함 이벤트발생기의역할은실버라이트가맡음 프로그래머는자싞이만든응용프로그램에이벤트처리기를필요에따라추가함
XAML 코드를이용하는방법 C# 코드를이용하는방법
받고자하는이벤트 ( 예를들어 Click) 와그이벤트를처리할함수인이벤트처리기의함수이름 ( 예를들어 button1_click) 을넣음 1. 속성창의이벤트탭을사용하거나, 2. Click= 를입력한상태에서 tab 키를누르면 Content 에서지정한이름이포함된이벤트처리기함수이름이자동으로등록되고, 한번더 tab 키를누르면이벤트처리기함수가 MainPage.xaml.cs ( 비하인드코드 ) 에등록됨
<Grid x:name="contentpanel" Grid.Row="1" Margin="12,0,12,0"> <Button Content="Button" Height="69" HorizontalAlignment="Left" Margin="83,60,0,0" Name="button1" VerticalAlignment="Top" Width="270" Click="button1_Click" /> </Grid>
private void button1_click(object sender, RoutedEventArgs e) { MessageBox.Show(" 버튺이눌려짐 "); }
C# 코드로직접이벤트처리기를등록 XAML 에서컨트롟을생성하고컨트롟의 x.name 속성을채워서, 비하인드코드인 cs 파일에서이들을다루는것임 += 연산자를이용해서이벤트를처리하기위한함수를등록하고나중에이벤트가발생할때이벤트처리기가자동으로호출되도록함 이를위임 (delegation) 이라고함
<Grid x:name="contentpanel" Grid.Row="1" Margin="12,0,12,0"> <Button Content="Button" Height="72" HorizontalAlignment="Left" Margin="41,56,0,0" Name="button1" VerticalAlignment="Top" Width="370" /> </Grid>
public MainPage() { InitializeComponent(); this.button1.click += new RoutedEventHandler(button1_Click); } void button1_click(object sender, RoutedEventArgs e) { MessageBox.Show(" 버튺이눌려짐 "); }
실버라이트에서유연한컨텎츠디자인과효율적인이벤트처리를위해제공하는기능 어떤개체에서이벤트가발생할때, 그부모개체들을거쳐해당이벤트가정의된최상위개체까지전파해서처리할수있게하는기술 이렇게이벤트가자식에서부모개체로전달되는행위를버블링 (bubbling) 이라고함 실버라이트에서는자식에서부모로이벤트가전달되는것만가능함
최상위개체 ( 부모 ) User Control 이벤트버블링 Canvas Canvas 이벤트발생 Rectangle StackPanel 컨트롟개체트리 자식개체
Design View 에서 Canvas 세개를내포되게만듬 <Canvas Height="500" HorizontalAlignment="Left" Margin="30,26,0,0" Name="canvas1" VerticalAlignment="Top" Width="393" Background="Blue" MouseLeftButtonDown="canvas1_MouseLeftButtonDown"> <Canvas Canvas.Left="26" Canvas.Top="26" Height="450" Name="canvas2" Width="346" Background="Green" MouseLeftButtonDown="canvas2_MouseLeftButtonDown"> <Canvas Canvas.Left="26" Canvas.Top="26" Height="404" Name="canvas3" Width="297" Background="Yellow" MouseLeftButtonDown="canvas3_MouseLeftButtonDown"/> </Canvas> </Canvas>
private void canvas1_mouseleftbuttondown(object sender, MouseButtonEventArgs e) { MessageBox.Show(" 첫번째캔버스 - MouseLeftButtonDown 이벤트 "); } private void canvas2_mouseleftbuttondown(object sender, MouseButtonEventArgs e) { MessageBox.Show(" 두번째캔버스 - MouseLeftButtonDown 이벤트 "); } private void canvas3_mouseleftbuttondown(object sender, MouseButtonEventArgs e) { MessageBox.Show(" 세번째캔버스 - MouseLeftButtonDown 이벤트 "); }
이벤트가더이상전파되지않도록하기위해서는, 해당이벤트처리기의두번째인자인 RoutedEventArgs 클래스개체의 Handled 속성값으로 true 를대입하면됨
private void canvas1_mouseleftbuttondown(object sender, MouseButtonEventArgs e) { e.handled = true; MessageBox.Show(" 첫번째캔버스 - MouseLeftButtonDown 이벤트 "); } private void canvas2_mouseleftbuttondown(object sender, MouseButtonEventArgs e) { e.handled = true; MessageBox.Show(" 두번째캔버스 - MouseLeftButtonDown 이벤트 "); } private void canvas3_mouseleftbuttondown(object sender, MouseButtonEventArgs e) { e.handled = true; MessageBox.Show(" 세번째캔버스 - MouseLeftButtonDown 이벤트 "); }
이벤트버블링이많이일어난경우, 만일어떤이벤트가최초로어떤개체에서발생했는지알고싶다면어떻게해야할까? 이를위해서는해당이벤트처리기의두번째인자인 RoutedEventArgs 클래스개체의 OriginalSource 속성을사용하면됨 부모자식관계의컨트롟개체트리가만들어짂상태이면, 버블링은자동으로활성화되어있으므로, 자식개체의이벤트처리기가설정되어있지않다면, 자동으로부모개체로이벤트버블링이됨 참고로, 현대의개체지향언어에서, 기본적으로개체의타입식별은리플렉션이라는기능에의지하는것이원칙임
<Canvas Height="500" HorizontalAlignment="Left" Margin="54,57,0,0" Name="canvas1" VerticalAlignment="Top" Width="353" Background="Blue" MouseLeftButtonDown="canvas1_MouseLeftButtonDo wn"> <Rectangle Canvas.Left="53" Canvas.Top="67" Height="76" Name="rectangle1" Stroke="Black" StrokeThickness="1" Width="252" Fill="Green" /> <StackPanel Canvas.Left="56" Canvas.Top="217" Height="103" Name="stackPanel1" Width="246" Background="Yellow" /> </Canvas>
if (e.originalsource is Rectangle) { MessageBox.Show("Rectangle 에서마우스클릭 "); } else if (e.originalsource is StackPanel) { MessageBox.Show("StackPanel 에서마우스클릭 "); } else { MessageBox.Show("Canvas 에서마우스클릭 "); }
이벤트의위임은 = 연산자보다는 += 연산자를주로사용함 왜냐하면, 특정개체에는이미시스템에의해위임된기존의이벤트처리기들이있는경우가많으며, 개발자는대개의경우, 이이벤트처리기들의큐 (queue) 에새로하나를더넣어주는경우이기때문임 닷넷구조에서는, 이러한큐구조를델리게이트체인 (delegate chain) 이라부름 드물게응용프로그램이종료되기전에이벤트처리기를제거해야할경우가있음 이를위해서는 -= 연산자를사용한구문을넣어주면됨 EventButton.Click -= EventButton_Click;
이벤트 이벤트모델 실버라이트이벤트 이벤트처리기 라우트된이벤트 이벤트라우팅중단 이벤트개체식별 이벤트처리기제거
1. 윈도우폰에서는기본적으로이벤트버블링이설정되어있다. 그렇다면, 안드로이드에서는이벤트버블링이기본적으로설정되어있을까? 아니면설정되어있지않을까? 2. 앞의예에서는 RoutedEventArgs 의 OriginalSource 속성을통해서이벤트개체를식별하였는데, 각자식개체의클래스가달랐다. 만일, 다른것은다동일한데, Canvas 에 StackPanel 개체는없고 Rectangle 개체만 3 개가나란히배열되어있다고하자. 특정개체를눌렀을때, 어느 Rectangle 개체가눌렸는지를알아내려면어떻게해야하는가? 물롞이벤트처리기는 Canvas 에만설정되어있다. ( 힌트 : C# 의리플렉션 reflection 기능을사용 )