데이터 바인딩 7

패널의 폭에 따라 아이콘 목록 배열

소스는 아이콘의 기본이 되는 이름만 가진 클래스 ListItem을 정의하고 있다.
xaml에서는 List의 ItemTemplate에서 Button을 지정한다.

Content 이름을 바인딩하고 있다. GridSplitter에서 아이콘 목록의 폭을 크게 했을 때 많은 아이콘을 보기 위해 ItemsPanel에 WrapPanel을 지정한다.

<Window x:Class="BindingDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:BindingDemo"
        Title="BindingDemo" Height="388" Width="246" DataContext="{Binding}">
    <Window.Resources>
        <x:Array x:Key="ListItems" Type="local:ListItem">
            <local:ListItem Name="Item1"/>
            <local:ListItem Name="Item2"/>
            <local:ListItem Name="Item3"/>
            <local:ListItem Name="Item4"/>
            <local:ListItem Name="Item5"/>
        </x:Array>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="100"/>
        </Grid.ColumnDefinitions>
        <GridSplitter Width="3" HorizontalAlignment="Right" VerticalAlignment="Stretch"/>
        <ListView Grid.Column="1" ItemsSource="{StaticResource ListItems}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding Name}" Width="50" Height="50" Margin="5"/>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal"
                            Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}}"/>
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
        </ListView>
    </Grid>
</Window>

 


GridSplitter 목록의 폭을 변경하면 다음과 같이 바뀐다.

처음 실행시 아이템 리스트 배열 패널의 폭 확장시 아이템 리스트 배열

 

namespace BindingDemo
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
        }
    }

    public class ListItem
    {
        public string Name { get; set; }

        public ListItem()
        {
        }
    }
}

다운로드 : BindingDemo_ItemAlign.zip

 

아이콘 목록 그룹보기

이이콘 목록을 그룹화 시킨다.

<Window x:Class="BindingDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:BindingDemo"
        Title="BindingDemo" Height="388" Width="246" DataContext="{Binding}">
    <Window.Resources>
        <x:Array x:Key="ListItems" Type="local:ListItem">
            <local:ListItem Name="Item1" GroupName="Group1"/>
            <local:ListItem Name="Item2" GroupName="Group1"/>
            <local:ListItem Name="Item3" GroupName="Group1"/>
            <local:ListItem Name="Item4" GroupName="Group2"/>
            <local:ListItem Name="Item5" GroupName="Group2"/>
        </x:Array>
        <CollectionViewSource x:Key="GroupItems" Source="{StaticResource ListItems}">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="GroupName"/>
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="100"/>
        </Grid.ColumnDefinitions>
        <GridSplitter Width="3" HorizontalAlignment="Right" VerticalAlignment="Stretch"/>
        <ListView Grid.Column="1" ItemsSource="{Binding Source={StaticResource GroupItems}}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding Name}" Width="50" Height="50" Margin="5"/>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal"
                            Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=ListView}}"/>
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.ContainerStyle>
                        <Style TargetType="GroupItem">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="GroupItem">
                                        <Expander Header="{Binding}">
                                            <Expander.Content>
                                                <ItemsPresenter/>
                                            </Expander.Content>
                                        </Expander>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
            </ListView.GroupStyle>
        </ListView>
    </Grid>
</Window>

 

namespace BindingDemo
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
        }
    }

    public class ListItem
    {
        public string GroupName { get; set; }
        public string Name { get; set; }

        public ListItem()
        {
        }
    }
}

cs 소스의 ListItem 클래스에 GroupName을 추가한다.  
xaml의 ListView의 ItemSource를 CollectionViewSource 하고 있다.
CollectionViewSource는 Source의 Collection을 그룹화 할 수 있다.
그룹화를 위한 키를 PropertyGorupDescription의 PropertyName에 지정한다.
ListView는 GroupStyle을 설정한다. 그룹화 된 Collection을 표시하는데 Expanderfmf 지정하고 있다.

다운로드 : BindingDemo_ItemGroup.zip

 

2개의 DataGrid의 칼럼폭 동기화

이번에는 2개의 DataGrid 칼럼 폭을 동기화 하는 예제이다.
하나의 DataGrid 칼럼 폭을 다른 DataGrid 칼럼 폭에 바인딩 하는 방법은 통하지 않는다.

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <DataGrid x:Name="dataGrid1" AutoGenerateColumns="False" Margin="5">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="Column1" Header="Data1"/>
                <DataGridTextColumn x:Name="Column2" Header="Data2"/>
                <DataGridTextColumn x:Name="Column3" Header="Data3"/>
                <DataGridTextColumn x:Name="Column4" Header="Data4"/>
                <DataGridTextColumn x:Name="Column5" Header="Data5"/>
            </DataGrid.Columns>
        </DataGrid>
        <GridSplitter Grid.Row="1" Height="3" HorizontalAlignment="Stretch" VerticalAlignment="Top"/>
        <DataGrid x:Name="dataGrid2" Grid.Row="1" AutoGenerateColumns="False" Margin="5">
            <DataGrid.Columns>
                <DataGridTextColumn Header = " Data1 "
                                Width = "{Binding ActualWidth, ElementName = Column1}"/>
                <DataGridTextColumn Header = "Data2"
                                Width = "{Binding ActualWidth, ElementName = Column2}"/>
                <DataGridTextColumn Header = "Data3"
                                Width = "{Binding ActualWidth , ElementName = Column3}"/>
                <DataGridTextColumn Header = "Data4"
                                Width = "{Binding ActualWidth, ElementName = Column4}"/>
                <DataGridTextColumn Header = "Data5"
                                Width = "{Binding ActualWidth, ElementName = Column5}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

 

namespace BindingDemo
{
    /// <summary>
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            dataGrid1.BindDataGridColumnsWidth(dataGrid2);
        }
    }

    public static class DataGridEx
    {
        public static void BindDataGridColumnWidth(this DataGridColumn col1, DataGridColumn col2)
        {
            var b = new Binding("Width");
            b.Source = col2;
            b.Mode = BindingMode.TwoWay;
            b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(col1, DataGridColumn.WidthProperty, b);
        }

        public static void BindDataGridColumnsWidth(this DataGrid dg1, DataGrid dg2)
        {
            for (int i = 0; i < dg1.Columns.Count; i++)
            {
                dg1.Columns[i].BindDataGridColumnWidth(dg2.Columns[i]);
            }
        }
    }
}

아직까지도 도 Win32 방식에 얽매여 있나보다. cs 소스에서 dataGrid1, dataGrid2 멤버가 어디에 선언 되어 있는지 찾고 있다. 컨트롤 네임을 MainWindow에서는 그대로 사용 할 수 있다는걸 자꾸 깜빡한다.

다운로드 : BindingDemo_DataGridColumn.zip
 

참고 )  http://cswpf.seesaa.net/index-10.html