Data Binding Intro (Windows 8)
-
Upload
gilbok-lee -
Category
Business
-
view
838 -
download
4
Transcript of Data Binding Intro (Windows 8)
개발자가 알아야할 Binding
강남 DataBinding 스타일Windows 8 앱개발자라면 꼭 알아야할
Non-DataBinding vs. DataBinding
<Grid>
<TextBlock x:Name=“TitleText”/>
<TextBlock x:Name=“SubTitleText”/>
</Grid>
TitleText.Text = item.Title;
SubTitleText.Text = item.SubTitle;
<Grid>
<TextBlock Text=“{Binding Title}”/>
<TextBlock Text=“{Binding SubTitle}”/>
</Grid>
this.DataContext = item;
버튼 누가 지웠어!
Non-DataBinding vs. DataBinding
<Grid>
<HyperlinkButton />
</Grid>
TitleText.Text = item.Title;
SubTitleText.Text = item.SubTitle;
컴파일 에러 발생!!!
<Grid>
<HyperlinkButton Content=“{Binding Title}”/>
</Grid>
this.DataContext = item;
컴파일 에러 없음
UI와 코드의 분리
개발자와 디자이너 업무영역의 분리
PEACE!
이번 앨범 타이틀 곡이 뭐야?
문맥
문맥
문맥 = Context
DataContext
FrameworkElement.DataContext거의 모든 UI는 FrameworkElement
가정
class Album
+ string CoverArt
+ string Name
+ Artist Artist class Artist
+ string ProfilerImage
+ string Name
class Chart
+ Album FirstAlbum
+ List<Album> Albums
자식에게 상속하는 DataContext
Visual Tree
<Grid x:Name=“LayoutRoot”
DataContext=“{Binding TopAlbum}”>
<Image Source=“{Binding CoverArt}”/>
<TextBlock Text=“{Binding Title}”/>
<StackPanel DataContext=“{Binding Artist}”>
<Image Source=“{Binding ProfileImage}”/>
<TextBlock Text=“{Binding Name}”/>
</StackPanel>
</Grid>
Grid(LayoutRoot)
TextBlock
Grid
Image
TextBlock
Image
자식에게 상속하는 DataContext
Visual Tree
<Grid x:Name=“LayoutRoot”
DataContext=“{Binding TopAlbum}”>
<Image Source=“{Binding CoverArt}”/>
<TextBlock Text=“{Binding Title}”/>
<StackPanel>
<Image Source=“{Binding Artist.ProfileImage}”/>
<TextBlock Text=“{Binding Artist.Name}”/>
</StackPanel>
</Grid>
Grid(LayoutRoot)
TextBlock
Grid
Image
TextBlock
Image
DataContext 주입법
var chart = GetKPopChart();
this.DataContext = chart;
<Page>
<Page.Resources>
<models:KPopChart x:Key=“Chart” />
</Page.Resources>
<Grid DataContext=“{StaticResource Chart}”>
…..
</Grid>
</Page>
In C#
In XAML
<Page>
<Page.DataContext>
<models:KPopChart x:Key=“Chart” />
</Page.DataContext>
<Grid >
…..
</Grid>
</Page>
Binding
문법
• Binding
– Text="{Binding Title}"
• Path (생략가능)
– Text=“{Binding Path=Title}”
• Source
– Text=“{Binding Name, Source={StaticResource MyViewModel}}”
• Converter
– Text=“{Binding PublishDate, Converter={StaticResource FamiliarDateString}}”
• ConverterParameter
– Text=“{Binding Price, Converter={StaticResource CurrencyConverter},
ConverterParameter=\{0:C2\}}”
{Binding }
• DataContext 자기 자신!
<TextBlock Text=“{Binding }” />
ItemsControl
ItemsControl 가족
• ListView
• GridView
• FlipView
• ListBox
• ComboBox
Control
ItemsControl
Selector
ListViewBase
ListView GridView
FlipView ListBox ComboBox
.ItemsSource 프로퍼티가 여기 정의
ItemsControl에서 DataContext 분배
var artists = new List<Artist>()
{
new Artist() { Name = “싸이”, CoverArt=“…”},
new Artist() { Name = “아이
유”, CoverArt=“…”},
new Artist() { Name = “싸이”, CoverArt=“…”},
new Artist() { Name = “아이
유”, CoverArt=“…”},
}
this.Artists = artist;
….
<ListView ItemsSource=“{Binding Artists}” />
XAML에서
CS에서
싸이
아이유
싸이
아이유
ItemTemplate과 DataContext
new Artist()
{
Name = “싸이”,
CoverArt=“…”,
}
ItemsSource의 인스턴스 하나가
ListViewItem 하나의 DataContext가
된다.
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel>
<Image Source=“{Binding CoverArt}”
/>
<TextBlock Text=“{Binding Name}” />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
싸이
In the hood
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
var contentControl = element as ContentControl;
contentControl.ContentTemplate = this.ItemTemplate;
contentControl.DataContext = item;
}
ItemsControl의 virtual PrepareContainerForItemOverride(…) 에서
INotifyPropertyChanged
INotifyCollectionChanged
약속
컨트롤은 INotifyPropertyChanged.PropertyChanged를 구독합니다.
컨트롤은 INotifyCollectionChanged.CollectionChanged를 구독합니다.
public abstract class BindableBase : INotifyPropertyChanged
public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged
Common/BindableBase.cs 에서
System.Collections.ObjectModel
이미 구현되어 있는 것
public abstract class SampleDataCommon : App4.Common.BindableBase
private string _title = string.Empty;
public string Title
{
get { return this._title; }
set { this.SetProperty(ref this._title, value); }
}
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
{
if (object.Equals(storage, value)) return false;
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
DataModel/SampleDataSource.cs에서
프로퍼티 예 : Title
In the Hood
List<Artist> vs. ObservableCollection<Artist>
this.Artist.Add(new Artist()); this.Artist.Add(new Artist());
싸이
아이유
싸이
싸이
아이유
싸이
아이유
Converter
어떤 필요, 어떤 니즈?
public List<string> Artists { get; set; }
…
Artists = new List<string>()
{
“싸이”,
“아이유”,
};
너랑 나랑 강남스타일
싸이, 아이유
샘플 ArtistConverternamespace MyApp
{
public class ArtistConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
// null 체크, value가 Ienumerable 타입이 아닐 때 예외처리 (생략)
var list = value as IEnumerable;
StringBuilder sb = new StringBuilder();
foreach (var item in list)
{
if (sb.Length > 0)
sb.Append(“, “);
sb.Append((string)item);
}
return sb.ToString();
}
}
}
사용법
너랑 나랑 강남스타일싸이, 아이유
인스턴스 생성 (어딘가에) -> 바인딩 식에서 잘 사용
In MyView.xaml (or App.xaml)
<Page>
<Page.Resources>
<conv:ArtistConverter x:Key=“ArtistConverter”/>
</Page.Resources>
<Grid x:Name=“LayoutRoot”>
…
<TextBlock Text=“{Binding Artists,
Converter={StaticResource ArtistConverter}”/>
</Grid>
</Page>
Blend 도와줘!
Sample Project
Code Review
GridApp 샘플 프로젝트에서
protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
// TODO: Create an appropriate data model for your problem domain to replace the sample data
var sampleDataGroups = SampleDataSource.GetGroups((String)navigationParameter);
this.DefaultViewModel["Groups"] = sampleDataGroups;
}
<common:LayoutAwarePage
x:Name="pageRoot"
x:Class="App4.GroupedItemsPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}“
…
<CollectionViewSource
x:Name="groupedItemsViewSource"
Source="{Binding Groups}"
GroupedItemsPage.xaml.cs에서
GroupedItemsPage.xaml에서
FIN
즐거운 해커쏜(θ) 되세요!