sourcecode

WPF에서 GridViewColumn 데이터를 자동 조정하고 오른쪽 정렬하려면 어떻게 해야 합니까?

copyscript 2023. 4. 19. 23:23
반응형

WPF에서 GridViewColumn 데이터를 자동 조정하고 오른쪽 정렬하려면 어떻게 해야 합니까?

어떻게 하면 좋을까요?

  • 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>

부분 답변:

Grid View Column, Kjetil 감사합니다.CellTemplate는 잘 작동하고 Auto Width는 물론 작동하지만 ObservativeCollection "Collection"이 열 너비보다 긴 데이터로 업데이트되면 열 크기가 자동으로 업데이트되지 않으므로 데이터의 초기 표시를 위한 솔루션일 뿐입니다.

<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>

각 열의 크기를 자동으로 조정하려면 Width="를 설정할 수 있습니다.자동"을 선택합니다.

ID 열의 텍스트를 오른쪽 정렬하려면 TextBlock을 사용하여 셀 템플릿을 작성하고 TextAlignment를 설정합니다.그런 다음 ListViewItem을 설정합니다.수평 컨텐츠 정렬(ListViewItem의 세터와 함께 스타일을 사용하여 셀 템플릿이 GridViewCell 전체를 채우도록 함).

어쩌면 더 간단한 해결책이 있을지도 모르지만, 이것은 효과가 있을 것이다.

참고: 이 솔루션에는 Window에 Horizal ContentAlignment=Filename이 모두 필요합니다.Resources and TextAlignment=Right in the CellTemplate.

<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>

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

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

    column.Width = double.NaN;
}

해당 열의 데이터가 업데이트될 때마다 데이터를 실행해야 합니다.

listview의 사이징도 변경할 경우 동작 패턴을 사용하여 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

이하의 클래스를 작성해, 필요에 따라서 애플리케이션 전체에서 사용하고 있습니다.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);
    }
}

Item Container Style이 있었기 때문에 Item Container Style에 수평 콘텐츠 얼라인먼트를 넣어야 했습니다.

    <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" /> 
    ....

사용자 1333423의 솔루션이 마음에 들었습니다만, 항상 모든 컬럼의 사이즈를 변경해, 일부 컬럼의 폭을 고정할 필요가 있었습니다.따라서 이 버전에서는 폭이 "Auto"로 설정된 열은 자동으로 크기가 조정되고 고정된 양으로 설정된 열은 자동으로 크기가 조정되지 않습니다.

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);
    }        
}

너무 늦은 건 알지만, 제 접근 방식은 다음과 같습니다.

<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 안에 있어요.

수락된 답변에 문제가 있었습니다(HorizontalAlignment=Response 부분을 놓쳐서 원래 답변을 조정했기 때문입니다).

이건 또 다른 기술이에요.Shared Size Group이 있는 그리드를 사용합니다.

참고: 그리드.ListView의 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>

리스트의 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;
    }
}

위의 @RandomEngy가 제시한 솔루션은 동작하지만 각 열의 가장 긴(가장 넓은) 값은 아니지만 가시적인 데이터(즉, 첫 번째 X 행)만을 기반으로 크기를 조정하는 데 문제가 있는 것으로 보입니다.

위의 문제를 해결하려면 다음을 수행합니다.

아래와 같이 목록 보기에도 변경된 컬렉션을 첨부합니다.

((INotifyCollectionChanged) MyListView.ItemsSource).CollectionChanged += CollectionChanged_Handler;

또한 뷰에서 발견된 가장 긴 콘텐츠를 저장하는 개인 maxWidth 속성을 선언합니다.

private double maxWidth = 200;//Whatever your default width is.

핸들러는 다음과 같습니다.

private void CollectionChanged_Handler(object sender, NotifyCollectionChangedEventArgs args)
{
   var gridView = (GridView)MyListView.View;
   if(gridView != null)
   {
      foreach( var column in gridView.Columns)
      {
         if(column.ActualWidth > maxWidth)
         {
            if (double.IsNaN(column.Width))
            {
                   maxWidth = column.ActualWidth;
                   column.Width = maxWidth ;
            }
            column.Width = double.NaN;
         }       
       }   
}

또한 대화상자를 실행하면 위도우가 이미 여러 행으로 채워지고 맨 위 행이 가장 길지 않을 수도 있습니다.위의 코드는 컬렉션이 변경될 때만 트리거되지만 데이터가 이미 로드되어 있고 대화 상자를 로드할 때 보이는 행이 가장 넓지 않기 때문에 위의 코드는 열의 크기를 조정할 수 없습니다.이 문제를 해결하려면 ListView_OnPreview 위의 핸들러를 호출합니다.Mouse Left Button 이벤트.아래와 같이

private void MyListView_OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
CollectionChanged_Handler(sender, null);
}

다른 사용자가 보기에서 가장 넓은 행 콘텐츠로 스크롤하면 위의 코드가 열 너비를 새로 고칩니다.

가장 긴의 자동 하여 설정함으로써 수 .Width="Auto" GridViewColumn.

<ListView ItemsSource="{Binding ...}" VirtualizingStackPanel.IsVirtualizing="False">
    <ListView.View>
        <GridView>
            <GridViewColumn Width="Auto"
                            DisplayMemberBinding="{Binding Name}"
                            Header="Name"/>
        </GridView>
    </ListView.View>
</ListView>

가상화는 디폴트로 유효하게 되어 있기 때문에, 표시되는 행만이 렌더링 됩니다.이것은 성능에 좋습니다.은 현재 너비를 데된다는 것입니다(예: 열 너비).Width="Auto" [(Virtualization)]를 비활성화하면 현재 .) [ ( Virtualization ) ]를 [ width ]는행의 합니다.그 결과 자동 너비 계산이 모든 행의 값을 고려합니다.

이것은 당신의 코드입니다.

<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>

음, 저는 방금 이 문제를 해결했고 IValue Converter로 해결했습니다.

public class GridViewColumHeaderWidthConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (double)value / 8;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

주의: 8은 Grid View Column의 수입니다.

이제 Xaml:

<ListView x:Name="TheListView" ItemsSource="{Binding Customers}">
    <ListView.View>
        <GridView>
            <!--  Id  -->
            <GridViewColumn Width="{Binding ElementName=TheListView, Path=ActualWidth, Converter={StaticResource GridViewColumHeaderWidthConverter}}">
                <GridViewColumnHeader Content="Id" />
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding CustomerId}" />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <!--  Code  -->
            <GridViewColumn Width="{Binding ElementName=TheListView, Path=ActualWidth, Converter={StaticResource GridViewColumHeaderWidthConverter}}">
                <GridViewColumnHeader Content="Code" />
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding CustomerCode}" />
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>

변환기 파일도 반드시 포함시켜 주세요.이 경우 App.xaml에서 컨버터를 정의했습니다.

<Application.Resources>
    <converters:GridViewColumHeaderWidthConverter x:Key="GridViewColumHeaderWidthConverter" />
</Application.Resources>

언급URL : https://stackoverflow.com/questions/560581/how-to-autosize-and-right-align-gridviewcolumn-data-in-wpf

반응형