340 likes | 529 Vues
강남 DataBinding 스타일 Windows 8 앱개발자라면 꼭 알아야할. 개발자가 알아야할 Binding. N on- DataBinding vs. DataBinding. <Grid> < TextBlock x:Name=“TitleText”/> < TextBlock x:Name =“SubTitleText”/> </Grid> TitleText.Text = item.Title ; SubTitleText.Text = item.SubTitle ;. <Grid>
E N D
강남DataBinding스타일 Windows 8 앱개발자라면꼭 알아야할 개발자가 알아야할 Binding
Non-DataBinding vs. DataBinding <Grid> <TextBlock x:Name=“TitleText”/> <TextBlock x:Name=“SubTitleText”/> </Grid> TitleText.Text = item.Title; SubTitleText.Text = item.SubTitle; <Grid> <TextBlockText=“{Binding Title}”/> <TextBlockText=“{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!
강남스타일! 문맥 너랑 나!
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}”/> <StackPanelDataContext=“{Binding Artist}”> <Image Source=“{Binding ProfileImage}”/> <TextBlock Text=“{Binding Name}”/> </StackPanel> </Grid> Grid(LayoutRoot) Image TextBlock Grid Image TextBlock
자식에게 상속하는 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) Image TextBlock Grid Image TextBlock
DataContext주입법 <Page> <Page.DataContext> <models:KPopChart/> </Page.DataContext> <Grid > ….. </Grid> </Page> In C# varchart = GetKPopChart(); this.DataContext = chart; <Page> <Page.Resources> <models:KPopChart x:Key=“Chart” /> </Page.Resources> <Grid DataContext=“{StaticResourceChart}”> ….. </Grid> </Page> In XAML
문법 • Binding • Text="{Binding Title}" • Path (생략가능) • Text=“{Binding Path=Title}” • Source • Text=“{Binding Name, Source={StaticResourceMyViewModel}}” • Converter • Text=“{Binding PublishDate, Converter={StaticResourceFamiliarDateString}}” • ConverterParameter • Text=“{Binding Price, Converter={StaticResourceCurrencyConverter}, ConverterParameter=\{0:C2\}}”
{Binding } • DataContext자기 자신! <TextBlock Text=“{Binding }” />
ItemsControl가족 • ListView • GridView • FlipView • ListBox • ComboBox Control ItemsControl .ItemsSource프로퍼티가 여기 정의 Selector ListViewBase FlipView ListBox ComboBox ListView GridView
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; …. <ListViewItemsSource=“{Binding Artists}” /> CS에서 싸이 아이유 싸이 아이유 XAML에서
ItemTemplate과 DataContext <ListView.ItemTemplate> <DataTemplate> <Grid> <StackPanel> <Image Source=“{Binding CoverArt}” /> <TextBlock Text=“{Binding Name}” /> </StackPanel> </Grid> </DataTemplate> </ListView.ItemTemplate> new Artist() { Name = “싸이”, CoverArt=“…”, } ItemsSource의 인스턴스 하나가 ListViewItem하나의 DataContext가 된다. 싸이
In the hood protected override void PrepareContainerForItemOverride(DependencyObject element, object item) { varcontentControl = element as ContentControl; contentControl.ContentTemplate = this.ItemTemplate; contentControl.DataContext = item; } ItemsControl의 virtual PrepareContainerForItemOverride(…) 에서
약속 컨트롤은 INotifyPropertyChanged.PropertyChanged를 구독합니다. 컨트롤은 INotifyCollectionChanged.CollectionChanged를 구독합니다. public abstract class BindableBase : INotifyPropertyChanged public class ObservableCollection<T> : Collection<T>, INotifyCollectionChanged Common/BindableBase.cs에서 System.Collections.ObjectModel
이미 구현되어 있는 것 DataModel/SampleDataSource.cs에서 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 boolSetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null) { if (object.Equals(storage, value)) return false; storage = value; this.OnPropertyChanged(propertyName); return true; } 프로퍼티 예 : Title In the Hood
List<Artist> vs. ObservableCollection<Artist> this.Artist.Add(new Artist()); this.Artist.Add(new Artist()); 싸이 싸이 아이유 아이유 싸이 싸이 아이유
어떤 필요, 어떤 니즈? public List<string> Artists { get; set; } … Artists = new List<string>() { “싸이”, “아이유”, }; 너랑 나랑 강남스타일 싸이, 아이유
샘플 ArtistConverter namespace MyApp { public class ArtistConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { // null 체크, value가 Ienumerable타입이 아닐 때 예외처리 (생략) var list = value as IEnumerable; StringBuildersb = 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={StaticResourceArtistConverter}”/> </Grid> </Page> 너랑 나랑 강남스타일 싸이, 아이유
GridApp샘플 프로젝트에서 GroupedItemsPage.xaml.cs에서 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 varsampleDataGroups = 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에서