Upload
youngwook-kim
View
667
Download
6
Embed Size (px)
Citation preview
Windows 10 앱 개발Tips & Tricks
오픈에스지
기술이사 송기수
오픈에스지
• OpenSG
• Solution, Consulting, SI and Education Service based on Microsoft .NET Technology
Its all about UWPUWP : Universal Windows Platform
1. XAML
2. Tool
3. Databinding
Agenda
XAML
•새로운 컨트롤• RelativePanel
• SplitView
• Adaptive UI• 예)계산기, 설정창
• View States
• Adaptive triggers
• XAML 성능• phase rendering
• deferred loading
상대적인 설정 값에 의해 자식 컨트롤을 배치
Relative Panel
레이아웃 컨트롤(Panel)
GridStack Panel
CanvasScroll Viewer
Border View BoxWrap Grid
Relative Panel
RelativePanel
• Element는 또 다른 Element의 상대적 위치를 가짐
• RelativePanel.Above = "BlueRect"
• RelativePanel.RightOf = " BlueRect "
• RelativePanel.Below = " BlueRect "
• RelativePanel.LeftOf = " BlueRect“
•적응형 UI 구현 최적• 보통 Visual State와 동시 사용됨
<RelativePanel>
<Rectangle x:Name="BlueRect" Fill="Blue" /><Rectangle x:Name="RedRect" RelativePanel.Below="BlueRect" />
</RelativePanel>
예)
<RelativePanel>
<Rectangle x:Name="BlueRect" Height="100" Width="200" Fill="Blue" />
<Rectangle x:Name="RedRect" Height="100" Width="100" Fill="Red"
RelativePanel.Below="BlueRect"RelativePanel.AlignHorizontalCenterWith="BlueRect" />
</RelativePanel>
Relative Panel
• 다른 Element를 기준으로 상대적 위치 설정• 다른 Element를 기준으로 상대적 정렬 설정• 기존 Panel과 같이 AttachedProperty로 설정됨
<RelativePanel>
<Rectangle x:Name="BlueRect" Height="100" Width="200" Fill="Blue" />
<Rectangle x:Name="RedRect" Height="100" Width="100" Fill="Red"RelativePanel.AlignHorizontalCenterWithPanel="True"RelativePanel.AlignVerticalCenterWithPanel="True" />
</RelativePanel>
Relative Panel
• Panel을 기준으로 상대적 정렬 설정
Demo
• RelativePanel
SplitView
IsPaneOpen="True" IsPaneOpen="False"
DisplayMode=
"Inline"
DisplayMode=
"Overlay"
DisplayMode=
"CompactInline"
DisplayMode=
"CompactOverlay"
Demo
• SplitView
Adaptive UI
Adaptive UI
• Visual States
• XAML에서 정의됨
•복잡하게 정의된 효과를 단순하게 선언하여 사용• 에니메이션등…
•블랜드를 통해서 정의• Xaml 직접 정의도 가능
• VisualStateManager.Goto(element, state, transition)
public MainPage(){
this.InitializeComponent();this.SizeChanged += (s, e) =>{
var state = "VisualState000min";if (e.NewSize.Width > 500)
state = "VisualState500min";else if (e.NewSize.Width > 800)
state = "VisualState800min";else if (e.NewSize.Width > 1000)
state = "VisualState1000min";VisualStateManager.GoToState(this, state, true);
};}
Adaptive triggers
•코드없이 XAML에서 설정만으로 상태전환 가능
•제공되는 기본 트리거• MinWindowHeight (Taller than this)
• MinWindowWidth (Wider than this)
<VisualState x:Name="VisualState500min"><VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="501" /></VisualState.StateTriggers>
</VisualState>
XAML 성능
• phase rendering
• deferred loading
X:Phase rendering
•기본값 0
•가능한 적은 단계로 관리
•연속적일 필요는 없음
<DataTemplate x:DataType="model:Monster"><Grid Width="200" Height="80"><TextBlock Text="{x:Bind Name}" /><TextBlock Text="{x:Bind StarSign}" x:Phase="1"/>
</Grid></DataTemplate>
deferred loading
•초기 로드되는 요소 최소화
•요소가 요구되기 전까지는 loading 되지 않는다
•요소가 요구되는 상황1. FindName()
2. GetTemplatedChild() (ControlTemplate 일경우)
3. Storyboard & VisualStates (내부적으로 FindName호출함)
<StackPanel x:Name="AdditionalProductPage" Visibility="Collapsed"
x:DeferLoadStrategy="Lazy">
<!– your lovely XAML goes here-->
</StackPanel>
deferred loading
•경량의 proxy element가 대신 생성됨
•이벤트는 element가 로딩된 후 등록됨
• Binding 동작도 element가 로딩된 후 완성됨• {x:Bind} 도 동일
2 Tool
•비주얼 스튜디오 2015 의 새로운 기능• 진단도구
• 중단점
• 직접실행창 : LINQ
• peek view
• 라이브 시각적 트리
• 라이브 속성 탐색기
진단도구
중단점
직접 실행창
• LINQ 실행가능
라이브 시각적 트리
라이브 속성 탐색기
Demo
•진단도구
•중단점
•직접실행창 : LINQ
• peek view
•라이브 시각적 트리
•라이브 속성 탐색기
3 Databinding
•기존 바인딩 개념• Classic Binding, {binding}
• 정적/동적 바인딩
• Converter
• INPC/INCC
•컴파일된 바인딩• Compiled Binding, {x:bind}
• 이벤트 바인딩
예) 정적 데이터 바인딩
바인딩 표현식 {StaticResource ….}
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"><TextBlock Text="나이 : " /><TextBlock Text="성 : " /><TextBlock Text="이름 : " /><TextBlock Text="여성 : " />…
예) 동적 데이터 바인딩
•바인딩 표현식 {Binding ….}
• DataContext 설정 필요
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">…<TextBox Text="{Binding PersonInfo.Age}" /><TextBox Text="{Binding PersonInfo.LastName}" /><TextBox Text="{Binding PersonInfo.FirstName}" /><CheckBox IsChecked="{Binding PersonInfo.IsFemale}" />…
INPC
• INotifyPropertyChanged
• UI 업데이트• Data -> UI
• ViewModel 과 Model에서 주로 구현됨
• 속성값의 변화가 있을 때 특정 이벤트 발생
INCC
• INotifyCollectionChanged
• UI 업데이트• Data -> UI
• ObservableCollection<T>, ReadOnlyObservableCollection<T>에서 구현됨
• 컬렉션에 변화가 있을 때 특정 이벤트 발생
바인딩 식 #1
<TextBox Text="{Binding
Converter
ConverterLanguage
ConverterParameter
ElementName
FallbackValue
Mode
Path
RelativeSource
Source
TargetNullValue
UpdateSourceTrigger}
Converter : 컨버터
ElementName : 요소 바인딩
FallbackValue : 기본값(바인딩이 유효하지 않을 때)
TargetNullValue : 기본값(대상 값이 null일 때)
UpdateSourceTrigger : 소스 반영시점
Converter
•바인딩 데이터를 변환하는 역할
• IValueConverter
Data -> UI 데이터를 UI에 표시하기 전에 호출되는 메서드
UI -> Data UI의 값을 데이터멤버에 할당하기 전에 호출되는 메서드종종 생략되곤 한다
Demo
• Classic binding
• FallbackValue
• TargetNullValue
• UpdateSourceTrigger
컴파일 바인딩
• compiled binding
•바인딩 성능 향상 & 기존의 편리함을 유지
•새로운 데이터 바인딩 원리
•컴파일타임에 바인딩의 일정작업이 진행됨
•바인딩식은 컴파일타임에 검증됨
∴런타임시 부하는 상대적으로 적음바인딩 선언은 코드로 자동 변환된 후 컴파일 됨런타임시의 리플렉션 코드 최소화변환된 코드는 디버깅 가능
바인딩 식 #2
<TextBox Text="{Binding
Converter
ConverterLanguage
ConverterParameter
ElementName
FallbackValue
Mode
Path
RelativeSource
Source
TargetNullValue
UpdateSourceTrigger}
<TextBox Text="{x:Bind
Converter
ConverterLanguage
ConverterParameter
ElementName
FallbackValue
Mode
Path
RelativeSource
Source
TargetNullValue
UpdateSourceTrigger}
컴파일 바인딩
•대상 타입의 명시적인 선언 필요
• =>해당 페이지의 멤버만 바인딩 가능
<Grid Background="{StaticResourceApplicationPageBackgroundThemeBrush}">
…<TextBox Text="{x:Bind sViewModel.PersonInfo.Age}" /><TextBox Text="{x:Bind sViewModel.PersonInfo.LastName}" /><TextBox Text="{x:Bind sViewModel.PersonInfo.FirstName}" /><CheckBox IsChecked="{x:Bind sViewModel.PersonInfo.IsFemale}" />…
컴파일 바인딩
public sealed partial class CompiledBindingPage : Page{
public SampleViewModel sViewModel { get; set; }public CompiledBindingPage(){
this.InitializeComponent();sViewModel = new SampleViewModel();
}}
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">…<TextBox Text="{x:Bind sViewModel.PersonInfo.Age}" /><TextBox Text="{x:Bind sViewModel.PersonInfo.LastName}" /><TextBox Text="{x:Bind sViewModel.PersonInfo.FirstName}" /><CheckBox IsChecked="{x:Bind sViewModel.PersonInfo.IsFemale}" />…
Demo
• Compiled binding
컴파일 바인딩
• Data Templates
<ListView ItemsSource="{x:Bind ViewModel.Employees}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:Employee">
<TextBlock Text="{x:Bind Name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
컴파일 바인딩
• Resource dictionary
</UserControl.Resources><ResourceDictionary>
<ResourceDictionary.MergedDictionaries><local:MyTemplates/>
</ResourceDictionary.MergedDictionaries></ResourceDictionary>
</UserControl.Resources>
<ResourceDictionary x:Class="MyNamespace.MyTemplates" xmlns:model="using:xBindSampleModel">
<DataTemplate x:Key="MyTemplate" x:DataType="model:Employee"><TextBlock Text="{x:Bind Name}" />
</DataTemplate></ResourceDictionary>
namespace MyNamespace{
public class MyTemplates{
public MyTemplates(){
InitializeComponent();}
}}
컴파일 바인딩
•이벤트 바인딩
•적용 가능한 함수 시그니처• 인자 없음 - void Select()• 이벤트 인자 타입 - void Select(object sender, RoutedEventArgs e)• - void Select(object sender, object e)• 오버로딩은 지원되지 않는다->하나의 메서드만 존재해야 함
• 모든 이벤트에 적용 가능함• Icommand & EventToCommand 대신 사용 가능함• - 그러나 특정 인자나 혹은 CanExecute와 같은 기능을 포함하지는 않음
<Button Click=“SelectEmployee">사원 정보 선택</Button>
<Button Click="{x:Bind Employee.Select}">사원 정보 선택</Button>
x:Bind
• 컴파일된 바인딩• 바인딩 표현식은 컴파일시에 검증된다
• Strongly-typed 바인딩• 리플렉션을 사용하지 않는다
• 페이지 자신의 멤버를 바인딩• DataContext와는 무관함
• 기본 모드는 OneTime• 기존의 OneWay, TwoWay모드도 가능함
• Classic Binding에서는 OneWay가 기본 모드임
• 기타 표준 바인딩 원리 준수• INotifyPropertyChanged, INotifyCollectionChanged, IObservableVector
x:Bind 고려할 점
• MVVM에서 적용?
• View와 ViewModel과의 coupling 문제
• JSON객체 혹은 untyped object일 경우 사용불가
• Classic Binding을 사용
•스타일에서의 사용
• {x:Bind}은 style에서 setters 로는 사용 불가
• {x:Bind}은 style에 정의된 DataTemplate 에서는 사용가능
{Binding} {x:Bind}
•예상 되는 패턴public sealed partial class CompiledBindingPage : Page{
public SampleViewModel sViewModel { get; set; }public CompiledBindingPage(){
this.InitializeComponent();
this.DataContextChanged += (s, e) =>
{
sViewModel = DataContext as SampleViewModel;
};}
}
Session Summary
• XAML• RelativePanel• SplitView
• Tool• 진단도구 : CPU, 메모리• 직접실행창 : LINQ• 라이브 시각적 트리, 속성 탐색기
•Databinding• INPC/INCC• {x:Bind}
감사합니다!