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>
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>
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.
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
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);
}
}
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" />
....
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);
}
}
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.
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>
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;
}
}