데이타바인딩(2)
ListBox에 ToString() 말고, 임의의 모습으로 나타내고자 할때 사용할수 있음.
Window.xaml
<Window x:Class="OneTimeDataBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:myClass="clr-namespace:OneTimeDataBinding"
Title="Window1" Height="236" Width="300" Loaded="Window_Loaded">
<Window.Resources>
<myClass:Code x:Key="cd" Name="_ResourceName" ></myClass:Code>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" Foreground="Blue"></TextBlock>
<TextBlock Text=":"></TextBlock>
<TextBlock Text="{Binding Path=Age}" Foreground="Chartreuse"></TextBlock>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid Height="289" x:Name="Grid1" DataContext="{StaticResource cd}">
<Grid.RowDefinitions>
<RowDefinition Height="65*" />
<RowDefinition Height="224*" />
</Grid.RowDefinitions>
<TextBox Margin="12,12,73,10" Name="textBox1" Text="{Binding Path=Name}" />
<Button HorizontalAlignment="Right" Margin="0,12,12,10" Name="button1" Width="55" Click="button1_Click">Button</Button>
<Grid Name="Grid2" Margin="0,12,0,100" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="132*" />
<ColumnDefinition Width="146*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="89.473*" />
<RowDefinition Height="23.527*" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Path=Name}" Margin="12,0,12,6" Grid.Row="1" Height="17.527" VerticalAlignment="Bottom"></TextBlock>
<TextBlock Text="{Binding Path=Age}" Margin="12,0,26,10" Grid.Row="1" Grid.Column="1" Height="13.527" VerticalAlignment="Bottom"></TextBlock>
<ListBox Margin="12,6,0,6" Name="listBox1" ItemsSource="{Binding}" Grid.ColumnSpan="2"
HorizontalAlignment="Left" Width="260" SelectionChanged="listBox1_SelectionChanged"
ItemTemplate="{StaticResource dt}" />
</Grid>
</Grid>
</Window>
Window.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace OneTimeDataBinding
{
/// <summary>
/// Window1.xaml에 대한 상호 작용 논리
/// </summary>
public partial class Window1 : Window
{
Code cd = new Code();
public Window1()
{
InitializeComponent();
cd.Name = "초기 코드값";
Grid1.DataContext = cd;
}
private void button1_Click(object sender, RoutedEventArgs e)
{
cd.Name = "변경 값";
//MessageBox.Show(cd.Name);
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
CodeList cd = new CodeList();
cd.Add(new Code() { Name = "Code1", Age=1});
cd.Add(new Code() { Name = "Code2", Age=2 });
cd.Add(new Code() { Name = "Code3", Age=3 });
listBox1.DataContext = cd;
}
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Grid2.DataContext = e.AddedItems;
}
}
///// <summary>
///// 단일 바인딩 모델에서 사용한 클래스.
///// </summary>
//public class Code
//{
// string name = string.Empty;
// public string Name { get; set; }
//}
/// <summary>
/// 코드 리스트
/// </summary>
public class CodeList : List<Code>
{
}
/// <summary>
///
/// 단방향 모델에서 사용한 클래스.
/// </summary>
public class Code : INotifyPropertyChanged
{
string name = string.Empty;
public string Name { get { return name; } set { name = value; Update("Name"); } }
int age = 0;
public int Age { get { return age; } set { age = value; Update("Age"); } }
#region INotifyPropertyChanged 멤버
public event PropertyChangedEventHandler PropertyChanged;
#endregion
public void Update(string PropertyName)
{
if( PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
public override string ToString()
{
return name;
}
}
}
특정 객체에 저장된 데이타가 출력되는 화면을 정의하여 템플릿화 할수 있는데
이를 데이타 템플릿이라 한다.
ObservableCollection<T> : 책에 오타 있으므로 철자 주의!
위 소스에서 이전, 다음 버튼을 추가후 각각 버튼 처리를 한다.
// 이전
private void button2_Click(object sender, RoutedEventArgs e)
{
ICollectionView view = CollectionViewSource.GetDefaultView(listBox1.DataContext);
view.MoveCurrentToPrevious();
if (view.IsCurrentBeforeFirst) view.MoveCurrentToFirst();
//Grid2.DataContext = view.CurrentItem as Code;
listBox1.SelectedItem = view.CurrentItem;
}
//다음
private void button3_Click(object sender, RoutedEventArgs e)
{
ICollectionView view = CollectionViewSource.GetDefaultView(listBox1.DataContext);
view.MoveCurrentToNext();
if (view.IsCurrentAfterLast) view.MoveCurrentToLast();
//Grid2.DataContext = view.CurrentItem as Code;
listBox1.SelectedItem = view.CurrentItem;
}
이때 새로운 데이타 추가시~~ CodeList 가 변경 되는데 이때 컨트롤에 적용시키는 기능이 포함되어 있지 않다.
INotifyPropertyChanged 인터페이스가 List<T>에는 적용되어 있지 않아 갱신되지 않으므로
WPF에서는 이를 적용한 ObservableCollection<T> 제너릭컬렉션에 데이타를 저장하면 자동으로 갱신된다.
테스트 해보니 일반 List<T>를 사용하여 추가기능을 구현했을때는
추가후 ListBox에 추가된 Item은 보이지 않았음.
ObservableCollection<T>를 사용하여 구현하니 추가시 바로 갱신되는것을 확인하였음.
public class oCodeList : ObservableCollection<Code>
{
}
public class Window1 : Window
{
...
private void Window_Loaded(object sender, RoutedEventArgs e)
{
oCodeList cd = new oCodeList();
// CodeList cd = new CodeList();
cd.Add(new Code() { Name = "Code1", Age=1});
cd.Add(new Code() { Name = "Code2", Age=2 });
cd.Add(new Code() { Name = "Code3", Age=3 });
listBox1.DataContext = cd;
}
/// 추가 기능
private void button4_Click(object sender, RoutedEventArgs e)
{
oCodeList ls = listBox1.DataContext as oCodeList;
//CodeList ls = listBox1.DataContext as CodeList;
if (ls != null)
ls.Add(new Code() { Name="add1", Age=ls.Count+1 });
}
}
컨트롤 데이타 바인딩
임의의 WPF 컨트롤에 설정된 데이타를 다른 컨트롤에 바인딩 할수도 있다.
이때 속성대 속성의 매칭을 통해 데이타의 이동이 발생한다.
간단히 바인딩 표현식이 바뀐다
<바인딩컨트롤
Background="{Binding ElementName=대상컨트롤이름, Path=대상컨트롤속성이름}" ...
/>
책페이지 321부터 간략히 설명되있음...
me : 바인딩에 대해 2회로 나누어 확인하였음.
DataTemplate를 가지고 표시되는 형태를 마음대로 바꿀수 있다는 점이 역시 흥미로웠음.
다른부분은 .Net 2.0에서 코딩량이 좀 되지만 나름 구현이 가능했던 것들이라...
WPF에서의 바인딩 구현방법이 좀더 편하다는 생각이 들기도 했지만... 데이타 타입별로 Class화 해야된다면 파일또한 많아 지겠구나 싶었음. 필요하다면 지금까지 해왔던 방법대로 DataTable을 바인딩 걸어서 써보고 싶음.
- 출처 : .Net 3.5 차세대 개발 프로그래밍 - 책에서 일부 정리 함. ( 저작권 문제시 삭제 할 것임. )
자세한 내용은 책을 통해 확인하시길...
'# 3) .Net ( Vs 2008 ) > WPF' 카테고리의 다른 글
툴을 제작 해서 프로젝트를... 진행하다! (0) | 2010.02.26 |
---|---|
WPF 3D (0) | 2009.12.29 |
데이타바인딩(1) (0) | 2009.12.28 |
이벤트 종류 & 명령 & 트리거 (0) | 2009.12.28 |
컨트롤 (0) | 2009.12.28 |