데이터 바인딩 1
https://hirudev.tistory.com/25
CollectionView
public partial class MainWindow : Window
{
private ObservableCollection<Person> people;
public MainWindow()
{
InitializeComponent();
people = new ObservableCollection<Person>( Enumerable.Range(0,10).Select((e, ret)=> new Person
{
Name = string.Format("test{0}", e),
Age = e
}) );
var v = CollectionViewSource.GetDefaultView(people);
v.Filter = x => {
var person = (Person)x;
return person.Age % 2 == 0;
};
v.SortDescriptions.Add(new SortDescription("Age", ListSortDirection.Descending));
this.listbox.DataContext = people;
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
↑ 필터, 정렬을 사용한 예
컬렉션 데이터 바인딩을 하면 내부적으로 직접 콜렉션이 바인딩되는 것이 아니고
사이에 CollectionView 라는 것이 암묵적으로 생성된다.
이 CollectionView 로 필터, 그룹화 처리가 가능하다.
public partial class MainWindow : Window
{
class AgeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int)value / 3;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
private ObservableCollection<Person> people;
public MainWindow()
{
InitializeComponent();
people = new ObservableCollection<Person>( Enumerable.Range(0,10).Select((e, ret)=> new Person
{
Name = string.Format("test{0}", e),
Age = e
}) );
var v = CollectionViewSource.GetDefaultView(people);
v.GroupDescriptions.Add(new PropertyGroupDescription("Age", new AgeConverter()));
this.listbox.DataContext = people;
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
<ListBox x:Name="listbox" ItemsSource="{Binding}">
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name, StringFormat={} {0}}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListBox.GroupStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Label Content="{Binding Name}"/>
<Label Content="{Binding Age}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
위 소스는 그룹화 시킨 예이다.
실시간 정렬 필터 그룹핑
프로퍼티 | 설명 |
IsLiveFilteringRequested | true 시 아이템이 추가될 때마다 실시간으로 필터링됨. |
IsLiveSortingRequested | true 시 아이템이 추가될 때마다 실시간으로 정렬됨. |
IsLiveGroupingRequested | true 시 아이템이 추가될 때마다 실시간으로 그룹화됨. |
// C# 코드 예제
people = new ObservableCollection<Person>( Enumerable.Range(0,10).Select((e, ret)=> new Person
{
Name = string.Format("test{0}", e),
Age = e
}) );
CollectionViewSource cvs = new CollectionViewSource();
cvs.Source = people;
cvs.IsLiveSortingRequested = true;
cvs.SortDescriptions.Add(new SortDescription("Age", ListSortDirection.Descending));
this.listbox.DataContext = cvs;
<!-- XAML 으로 작성했을 때의 예제 -->
<Window.Resources>
<CollectionViewSource
x:Key="Source"
Source="{Binding}"
IsLiveFilteringRequested="True"
IsLiveGroupingRequested="True"
IsLiveSortingRequested="True" >
<CollectionViewSource.LiveSortingProperties>
<System:String>Age</System:String>
</CollectionViewSource.LiveSortingProperties>
<CollectionViewSource.LiveGroupingProperties>
<System:String>Age</System:String>
</CollectionViewSource.LiveGroupingProperties>
<CollectionViewSource.LiveFilteringProperties>
<System:String>Age</System:String>
</CollectionViewSource.LiveFilteringProperties>
</CollectionViewSource>
</Window.Resources>
현재 선택항목을 바인딩하는 방법
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainWindowViewModel
{
People = new ObservableCollection<Person>(Enumerable.Range(0, 10).Select(
x => new Person {
Name = string.Format("test {0}", x),
Age = x
}
))
};
}
}
public class MainWindowViewModel
{
public ObservableCollection<Person> People { get; set; }
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DataGrid IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding People}" Grid.Column="0" Grid.Row="0" />
<StackPanel Grid.Column="1">
<TextBlock Text="Name" />
<TextBox TextWrapping="Wrap" Text="{Binding People/Name}" />
<TextBlock Text="Age" />
<TextBox TextWrapping="Wrap" Text="{Binding People/Age}" />
</StackPanel>
</Grid>
다른 쓰레드에서 콜렉션 조작
<DataGrid x:Name="datagrid" />
public partial class MainWindow : Window
{
private ObservableCollection<Person> people;
public MainWindow()
{
InitializeComponent();
// Age 0 ~ 9 까지 데이터바인딩
people = new ObservableCollection<Person>(Enumerable.Range(0, 10).Select(
x => new Person
{
Name = string.Format("test {0}", x),
Age = x
}
));
this.datagrid.ItemsSource = people;
// 콜렉션 조작을 락을 할 수 있게 설정.
BindingOperations.EnableCollectionSynchronization(people, new object());
// 다른 쓰레드 생성 Age 10 ~ 19까지
Task task = new Task(() =>
{
for (int i = 10; i < 20; i++)
{
people.Add(new Person { Name = "test", Age = i });
Thread.Sleep(1000);
}
});
task.Start();
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
'Windows > C#/WPF' 카테고리의 다른 글
[WPF] 나중에 참고할 링크 (0) | 2021.05.12 |
---|---|
커멘드 (0) | 2021.05.12 |
데이터 바인딩 1 (0) | 2021.05.09 |
리소스 & ControlTemplate (0) | 2021.05.08 |
스타일 (0) | 2021.05.08 |
댓글