Comment se positionner et aligner à droite les données GridViewColumn dans WPF?

Comment puis-je:

  • droit-aligner le texte dans la colonne ID
  • rendre chacune des colonnes taille automatique en fonction de la longueur du texte de la cellule avec les données les plus longues visibles?

voici le code:

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

réponse partielle:

Merci Kjetil, le GridViewColumn.CellTemplate fonctionne bien et la largeur automatique fonctionne bien sûr, mais quand le ObservativeCollection "Collection" est mis à jour avec des données plus longues que la colonne Largeur, les tailles de colonne ne se mettent pas à jour eux-mêmes de sorte que ce n'est qu'une solution pour l'affichage initial des données:

<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>
74
demandé sur akjoshi 2009-02-18 13:52:29

9 réponses

pour faire autosize chacune des colonnes vous pouvez définir Width=" Auto " sur le GridViewColumn.

pour aligner à droite le texte dans la colonne ID, vous pouvez créer un modèle de cellule en utilisant une zone de texte et définir L'alignement du texte. Ensuite, mettez la ListViewItem.HorizontalContentAlignment (en utilisant un style avec un setter sur la ListViewItem) pour faire le modèle de cellule remplir le GridViewCell entier.

peut-être qu'il y a une solution plus simple, mais cela devrait fonctionner.

Note: la solution nécessite à la fois HorizontalContentAlignment=Stretch dans Window.Ressources et TextAlignment=Right dans le 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>
92
répondu Kjetil Watnedal 2010-12-24 17:19:24

si la largeur du contenu change, vous devrez utiliser ce bit de code pour mettre à jour chaque colonne:

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

    column.Width = double.NaN;
}

vous devez le lancer à chaque fois que les données pour cette colonne mises à jour.

33
répondu RandomEngy 2009-12-19 00:14:54

si votre listview est aussi re-dimensionné, vous pouvez utiliser un pattern de comportement pour re-dimensionner les colonnes pour s'adapter à la largeur complète de ListView. Presque la même chose que toi avec grid.colonne définitions

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

voir le lien suivant pour quelques exemples et le lien vers le code source http://lazycowprojects.tumblr.com/post/7063214400/wpf-c-listview-column-width-auto

17
répondu Rolf Wessels 2011-06-30 02:36:16

j'ai créé la classe suivante et je l'ai utilisée dans l'ensemble de l'application chaque fois que requis à la place de 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);
    }
}
9
répondu user1333423 2016-06-08 20:31:21

depuis que j'ai eu un ItemContainerStyle j'ai dû mettre L'Alignementcontent horizontal dans le ItemContainerStyle

    <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" /> 
    ....
7
répondu paparazzo 2011-08-01 16:03:20

j'ai aimé la solution de user1333423 sauf qu'il a toujours re-dimensionné chaque colonne; je devais permettre à certaines colonnes d'être la largeur fixe. Donc, dans cette version des colonnes de largeur réglé sur "Auto" s'auto-de taille moyenne et ceux fixés à un montant fixe ne sera pas redimensionnée automatiquement.

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);
    }        
}
4
répondu jv_ 2015-05-15 07:32:19

je sais que c'est trop tard, mais voici ma démarche:

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

l'idée principale est de lier la largeur de l'élément cellTemplete à la largeur de la colonne Viewgrid. Width=100 est la largeur par défaut utilisée jusqu'à la première redimensionnement. Il n'y a pas tout le code derrière. Tout est dans le code xaml.

2
répondu Azzy Elvul 2015-05-25 07:39:26

j'ai eu des problèmes avec la réponse acceptée (parce que j'ai manqué la partie alignement horizontal=étirement et j'ai modifié la réponse originale).

c'est une autre technique. Il utilise une grille avec un SharedSizeGroup.

Note: la grille .IsSharedScope=true sur ListView.

<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>
1
répondu Adam Tegen 2010-12-24 17:22:09

j'ai créé une fonction pour mettre à jour les en-têtes de colonne GridView pour une liste et l'appeler chaque fois que la fenêtre est redimensionnée ou que listview met à jour sa mise en page.

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;
    }
}
1
répondu Andrei Rogobete 2015-03-20 10:27:36