WPF에서 GridViewColumn 데이터를 자동 크기 조정하고 오른쪽 정렬하는 방법은 무엇입니까?


89

내가 어떻게 할 수있는:

  • ID 열의 텍스트를 오른쪽 맞춤
  • 보이는 데이터가 가장 긴 셀의 텍스트 길이에 따라 각 열의 크기를 자동으로 조정 하시겠습니까?

다음은 코드입니다.

<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}" Width="40"/>
            <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="100" />
            <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}"/>
        </GridView>
    </ListView.View>
</ListView>

부분 답변 :

감사합니다 Kjetil, GridViewColumn.CellTemplate은 잘 작동하고 자동 너비는 물론 작동하지만 ObservativeCollection "컬렉션"이 열 너비보다 긴 데이터로 업데이트되면 열 크기가 자체적으로 업데이트되지 않으므로 데이터의 초기 표시 :

<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="ID" Width="Auto">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Id}" TextAlignment="Right" Width="40"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="Auto" />
            <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="Auto"/>
        </GridView>
    </ListView.View>
</ListView>

1
자동 크기 조정 문제에 대한 해결책을 찾았습니까? 저도 같은 일을 겪고 있습니다.
Oskar

2
@Oskar-목록의 가상화는 자동 솔루션을 방지합니다. 목록은 현재 보이는 항목 만 알고 그에 따라 크기를 설정합니다. 목록 아래에 더 많은 항목이 있으면 해당 항목을 알지 못하므로 설명 할 수 없습니다. ProgrammingWPF-Sells-Griffith 책은 데이터 바인딩을 사용하는 경우 수동 열 너비를 권장합니다. :(
기슈

@Gishu 감사합니다, 실제로 말이됩니다 ..
Oskar

MVVM을 사용하고 바인딩 값이 변경되면 @Rolf Wessels 답변을 참조하십시오.
Jake Berger

답변:


104

각 열의 크기를 자동으로 조정하려면 GridViewColumn에서 Width = "Auto"를 설정할 수 있습니다.

ID 열의 텍스트를 오른쪽 정렬하려면 TextBlock을 사용하여 셀 템플릿을 만들고 TextAlignment를 설정할 수 있습니다. 그런 다음 ListViewItem.HorizontalContentAlignment (ListViewItem에 setter가있는 스타일 사용)를 설정하여 셀 템플릿이 전체 GridViewCell을 채우도록합니다.

더 간단한 해결책이있을 수 있지만 이것은 작동합니다.

참고 : 솔루션에는 Window.Resources의 HorizontalContentAlignment = Stretch 및 CellTemplate의 TextAlignment = Right 가 모두 필요합니다 .

<Window x:Class="WpfApplication6.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
    <Style TargetType="ListViewItem">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    </Style>
</Window.Resources>
<Grid>
    <ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="ID" Width="40">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Id}" TextAlignment="Right" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="Auto" />
                <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="Auto"/>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>
</Window>

@Kjetil-이 설정을 특정 열에 적용 할 수 있습니까?
Gishu

15
+1 : <Setter Property = "HorizontalContentAlignment"Value = "Stretch"/>
Helge Klein

멋지지만 15 개의 열이 있는데 모두에 대해 셀 템플릿을 반복하지 않아도되는 방법이 있습니까?
Nitin Chaudhari 2012 년

7
GridViewColumn에서 DisplayMemberBinding을 제거하는 것을 잊은 경우에도 작동하지 않습니다. 그러면 템플릿은 아무 효과가 없습니다.
floele 2013-04-11

@Mohamed 왜 그렇지 않습니까?
NotALie입니다.

37

내용의 너비가 변경되면 다음 코드를 사용하여 각 열을 업데이트해야합니다.

private void ResizeGridViewColumn(GridViewColumn column)
{
    if (double.IsNaN(column.Width))
    {
        column.Width = column.ActualWidth;
    }

    column.Width = double.NaN;
}

해당 열에 대한 데이터가 업데이트 될 때마다 실행해야합니다.


1
이것을 무엇에 첨부 하시겠습니까?
Armentage

1
그리드 데이터를 업데이트 한 후 GridViewColumn에서 수동으로 실행합니다. ViewModel이 있으면 PropertyChanged 이벤트를 구독하고 실행할 수 있습니다.
RandomEngy

+1 감사합니다! 이것은 나를 많이 도왔습니다! 이 질문과 관련이 없지만 어쨌든 : GUI를 통해 런타임에 열을 동적으로 추가 / 제거 할 수있는 사용자 지정 List / GridView를 구현했습니다. 그러나 열을 제거하고 다시 추가하면 더 이상 나타나지 않습니다. 첫째, (어떤 이유로 든) 전혀 추가되지 않았다고 생각했지만 (Snoop 사용) 실제로 추가되었지만 ActualWidth가 0이라는 것을 알았습니다 (자동 크기가 조정되었으며 열이 제거됨). 이제 열에 다시 추가 한 후 코드를 사용하여 열을 올바른 너비로 설정합니다. 감사합니다!
gehho 2011

내 문제에 대한 간단한 해결책!
Gqqnbig

+1 완벽합니다! 이것이 답변으로 표시되기를 바랍니다. 열이 정의 된 XAML에 x : Name = "gvcMyColumnName"을 추가하여 뒤에있는 코드에서 액세스 할 수 있도록했습니다. 챔피언처럼 작동합니다.
K0D4 2013

19

목록보기도 크기가 조정되는 경우 동작 패턴을 사용하여 전체 ListView 너비에 맞게 열 크기를 조정할 수 있습니다. grid.column 정의를 사용하는 것과 거의 동일합니다.

<ListView HorizontalAlignment="Stretch"
          Behaviours:GridViewColumnResize.Enabled="True">
        <ListViewItem></ListViewItem>
        <ListView.View>
            <GridView>
                <GridViewColumn  Header="Column *"
                                   Behaviours:GridViewColumnResize.Width="*" >
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBox HorizontalAlignment="Stretch" Text="Example1" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>

몇 가지 예와 소스 코드에 대한 링크는 다음 링크를 참조하십시오. http://lazycowprojects.tumblr.com/post/7063214400/wpf-c-listview-column-width-auto


이것은 멋지다. 문제를 해결하고 찾고있는 모든 , n , Auto 기능을 제공합니다.
Designpattern

이것이 제가 찾던 것입니다. : D
Jake Berger 2011 년

참고 : 버그가있는 것 같습니다. ListView가 세로로 크기가 조정되면 세로 스크롤 막대가 나타나는 지점까지 스크롤 막대가 사라질 때까지 열 너비가 계속 증가합니다.
Jake Berger 2011 년

1
이 게시물 은 이전 의견에서 설명한 동작에 대한 통찰력을 제공 할 수 있습니다.
Jake Berger

멋지다. 코드와 사이트를 모두 의미한다.). 더 엄격한 요구 사항이있을 때 유용 할 것이라고 생각합니다.
Gqqnbig

12

다음 클래스를 만들고 필요한 곳에서 응용 프로그램 전체에서 사용했습니다 GridView.

/// <summary>
/// Represents a view mode that displays data items in columns for a System.Windows.Controls.ListView control with auto sized columns based on the column content     
/// </summary>
public class AutoSizedGridView : GridView
{        
    protected override void PrepareItem(ListViewItem item)
    {
        foreach (GridViewColumn column in Columns)
        {
            // Setting NaN for the column width automatically determines the required
            // width enough to hold the content completely.

            // If the width is NaN, first set it to ActualWidth temporarily.
            if (double.IsNaN(column.Width))
              column.Width = column.ActualWidth;

            // Finally, set the column with to NaN. This raises the property change
            // event and re computes the width.
            column.Width = double.NaN;              
        }            
        base.PrepareItem(item);
    }
}

7

ItemContainerStyle이 있으므로 ItemContainerStyle에 HorizontalContentAlignment를 넣어야했습니다.

    <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=FieldDef.DispDetail, Mode=OneWay}" Value="False">
                         <Setter Property="Visibility" Value="Collapsed"/>
                    </DataTrigger>
                </Style.Triggers>
                <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 
    ....

6

나는 항상 모든 열의 크기를 조정한다는 점을 제외하고는 user1333423의 솔루션을 좋아했습니다. 일부 열의 너비를 고정해야했습니다. 따라서이 버전에서는 너비가 "자동"으로 설정된 열의 크기가 자동으로 조정되고 고정 된 양으로 설정된 열의 크기는 자동으로 조정되지 않습니다.

public class AutoSizedGridView : GridView
{
    HashSet<int> _autoWidthColumns;

    protected override void PrepareItem(ListViewItem item)
    {
        if (_autoWidthColumns == null)
        {
            _autoWidthColumns = new HashSet<int>();

            foreach (var column in Columns)
            {
                if(double.IsNaN(column.Width))
                    _autoWidthColumns.Add(column.GetHashCode());
            }                
        }

        foreach (GridViewColumn column in Columns)
        {
            if (_autoWidthColumns.Contains(column.GetHashCode()))
            {
                if (double.IsNaN(column.Width))
                    column.Width = column.ActualWidth;

                column.Width = double.NaN;                    
            }          
        }

        base.PrepareItem(item);
    }        
}

2

나는 이것이 너무 늦었다는 것을 알고 있지만 여기에 내 접근 방식이 있습니다.

<GridViewColumn x:Name="GridHeaderLocalSize"  Width="100">      
<GridViewColumn.Header>
    <GridViewColumnHeader HorizontalContentAlignment="Right">
        <Grid Width="Auto" HorizontalAlignment="Right">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="100"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" Text="Local size" TextAlignment="Right" Padding="0,0,5,0"/>
        </Grid>
    </GridViewColumnHeader>
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
    <DataTemplate>
        <TextBlock Width="{Binding ElementName=GridHeaderLocalSize, Path=Width, FallbackValue=100}"  HorizontalAlignment="Right" TextAlignment="Right" Padding="0,0,5,0" Text="Text" >
        </TextBlock>
    </DataTemplate>
</GridViewColumn.CellTemplate>

주요 아이디어는 cellTemplete 요소의 너비를 ViewGridColumn의 너비에 바인딩하는 것입니다. 너비 = 100은 처음 크기를 조정할 때까지 사용되는 기본 너비입니다. 뒤에 코드가 없습니다. 모든 것이 xaml에 있습니다.


이 솔루션에 영감을 받아 한 열의 너비를 채울 수 있습니다. <GridViewColumn Width = "{Binding RelativeSource = {RelativeSource AncestorType = ListView}, Path = ActualWidth}">
J. Andersen

1

수락 된 답변에 문제가 있습니다 (HorizontalAlignment = Stretch 부분을 놓치고 원래 답변을 조정했기 때문에).

이것은 또 다른 기술입니다. SharedSizeGroup이있는 그리드를 사용합니다.

참고 : ListView 의 Grid.IsSharedScope = true .

<Window x:Class="WpfApplication6.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
    <ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}" Grid.IsSharedSizeScope="True">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="ID" Width="40">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                             <Grid>
                                  <Grid.ColumnDefinitions>
                                       <ColumnDefinition Width="Auto" SharedSizeGroup="IdColumn"/>
                                  </Grid.ColumnDefinitions>
                                  <TextBlock HorizontalAlignment="Right" Text={Binding Path=Id}"/>
                             </Grid>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="Auto" />
                <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="Auto"/>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>
</Window>

너비가 GridViewColumnas 40이고 열 정의 너비를 Auto? 말이 안 돼.
BK

1

목록의 GridView 열 머리글을 업데이트하는 함수를 만들고 창의 크기가 조정되거나 목록보기가 레이아웃을 업데이트 할 때마다 호출합니다.

public void correctColumnWidths()
{
    double remainingSpace = myList.ActualWidth;

    if (remainingSpace > 0)
    {
         for (int i = 0; i < (myList.View as GridView).Columns.Count; i++)
              if (i != 2)
                   remainingSpace -= (myList.View as GridView).Columns[i].ActualWidth;

          //Leave 15 px free for scrollbar
          remainingSpace -= 15;

          (myList.View as GridView).Columns[2].Width = remainingSpace;
    }
}

0

이것은 당신의 코드입니다

<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}" Width="40"/>
            <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="100" />
            <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}"/>
        </GridView>
    </ListView.View>
</ListView>

이 시도

<ListView Name="lstCustomers" ItemsSource="{Binding Path=Collection}">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Id}" Width="Auto">
               <GridViewColumnHeader Content="ID" Width="Auto" />
            </GridViewColumn>
            <GridViewColumn DisplayMemberBinding="{Binding FirstName}" Width="Auto">
              <GridViewColumnHeader Content="First Name" Width="Auto" />
            </GridViewColumn>
            <GridViewColumn DisplayMemberBinding="{Binding LastName}" Width="Auto">
              <GridViewColumnHeader Content="Last Name" Width="Auto" />
            </GridViewColumn
        </GridView>
    </ListView.View>
</ListView>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.