내용 보기

작성자

관리자 (IP : 172.17.0.1)

날짜

2020-07-10 02:25

제목

[WPF] 기본 ListView 컬럼 자동으로 사이즈에 맞게 Fill 시키기


ListView 컨트롤의 컬럼 Width 사이즈를 자동으로 Fill 시키는 방법
DependencyProperty를 사용하여 컨트롤의 속성으로 설정하도록 구현한다.

The Code-behind

다음과 같이 ListViewColumns에 해당 되는 DependencyProperty를 구현한다.


using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
 
namespace Commons.Utils
{
    /// <summary>
    /// 리스트뷰 컬럼들을 리스트뷰 컨트롤에 맞게 Fill 하는 클래스
    /// </summary>
    public class ListViewColumns : DependencyObject
    {
        public static readonly DependencyProperty StretchProperty =
            DependencyProperty.RegisterAttached("Stretch", typeof(Boolean), typeof(ListViewColumns),
            new UIPropertyMetadata(true, null,
                (o, e) =>
                {
                    ListView lv = o as ListView;
                    if (lv == null)
                    {
                        throw new ArgumentException("This property may only be used on ListViews");
                    }

                    lv.Loaded += lv_Loaded;
                    lv.SizeChanged += lv_SizeChanged;

                    return e;
                }
            )
            );

        public static bool GetStretch(DependencyObject obj)
        {
            return (bool)obj.GetValue(StretchProperty);
        }

        public static void SetStretch(DependencyObject obj, bool value)
        {
            obj.SetValue(StretchProperty, value);
        }

        static void lv_Loaded(object sender, RoutedEventArgs e)
        {
            ListView lv = sender as ListView;

 	        // Set initial column widths
            SetColumnWidths(lv);
        }

        static void lv_SizeChanged(object sender, SizeChangedEventArgs e)
        {
 	        ListView lv = sender as ListView;

            SetColumnWidths(lv);
        }

        private static void SetColumnWidths(ListView listView)
        {
            // Read unsized columns from Tag property
            List<GridViewColumn> columns = listView.Tag as List<GridViewColumn>;
            double specifiedWidth = 0;
            GridView gridView = listView.View as GridView;

            if (gridView != null)
            {
                if (columns == null)
                {
                    // Create columns list if first run
                    columns = new List<GridViewColumn>();

                    // Get all unsized columns
                    foreach (GridViewColumn column in gridView.Columns)
                    {
                        if (column.Width < 0)
                        {
                            specifiedWidth += column.ActualWidth;
                        }
                        else
                        {
                            columns.Add(column);
                        }
                    }
                }
                else
                {
                    // Get all unsized columns
                    foreach (GridViewColumn column in gridView.Columns)
                    {
                        if (columns.Contains(column) == false)
                        {
                            specifiedWidth += column.ActualWidth;
                        }
                    }
                }

                // Share remaining width equally among unsized columns
                double decSpace = 10;
                if (columns.Count > 0)
                {
                    decSpace = decSpace / columns.Count;
                }

                if (listView.ActualWidth > 0)
                {
                    foreach (GridViewColumn column in columns)
                    {
                        double newWidth = (listView.ActualWidth - specifiedWidth) / columns.Count;
                        if (newWidth >= 0)
                        {
                            column.Width = newWidth - decSpace;
                        }
                    }

                    // Store the unsized columns for later use
                    listView.Tag = columns;
                }
            }
        }
    }
}


The XAML

ListView 컨트롤에 적용은 다음과 같이 ListView 컨트롤의 속성으로 적용 할 수 있다.

다음과 같이 네임스페이스를 추가하고

xmlns:Util="clr-namespace:Commons.Utils;assembly=Commons"

ListVuew 컨트롤에 위에서 만든 DependencyProperty 속성을 사용해 컬럼을 자동 Fill시키도록 설정 한다.

<ListView x:Name="xApproachList" Util:ListViewColumns.Stretch="True" ItemsSource="{Binding ApproachList}" SelectedItem="{Binding SelectedApproachInfo}" SelectionMode="Single" HorizontalContentAlignment="Stretch" Style="{DynamicResource sListView}">
                <ListView.ItemContainerStyle>
                    <Style BasedOn="{StaticResource sListViewItem}" TargetType="ListViewItem">
                        <EventSetter Event="MouseDoubleClick" Handler="ListViewItemDoubleClick" />
                    </Style>
                </ListView.ItemContainerStyle>
                <ListView.View>
                    <GridView>
                        <GridViewColumn Width="100" Header="망 구분">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding Category, Converter={StaticResource EnumCategoryConverter}}" TextAlignment="Center" TextTrimming="CharacterEllipsis"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>

                        <GridViewColumn Width="120" Header="제한 IP">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding ApproachIPAddress}" TextAlignment="Center" TextTrimming="CharacterEllipsis"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>

                        <GridViewColumn Width="100" Header="사용 분류">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding IsApproach, Converter={StaticResource BoolApproachConverter}}" TextAlignment="Center" TextTrimming="CharacterEllipsis"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                    </GridView>
                </ListView.View>
            </ListView>

위 처럼 ListView 컨트롤에 Custom DependancyProperty를 사용해서 적용할 수 있다.


출처1

출처2