WPF - 如何在 ListView 中居中列数据?

Posted

技术标签:

【中文标题】WPF - 如何在 ListView 中居中列数据?【英文标题】:WPF - How to center column data in ListView? 【发布时间】:2010-12-12 01:52:14 【问题描述】:

我仍在学习 WPF,但我对应该非常简单的事情感到非常困惑。我想要做的是将第 3 列和第 4 列的内容居中。当我运行它时,列左对齐:

<ListView Margin="0" x:Name="listMonitoredUrls" AlternationCount="1"
          ItemsSource="Binding"  >
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Description" DisplayMemberBinding="Binding FriendlyDesc"/>
            <GridViewColumn Header="Url" DisplayMemberBinding="Binding Url"/>
            <GridViewColumn Header="Frequency">
                <GridViewColumn.CellTemplate >
                    <DataTemplate>
                        <TextBlock Text="Binding ScanFrequencyMinutes"
                                   HorizontalAlignment="Center"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Next Scan"  >
                <GridViewColumn.CellTemplate >
                    <DataTemplate>
                        <TextBlock Text="Binding TimeNextScanStr"
                                   HorizontalAlignment="Center"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

我真的开始喜欢 WPF,但是像这样一些简单的事情似乎真的很难。

【问题讨论】:

对不起,我的回答有点晚了,但是,我遇到了同样的问题,并通过在 DataTemplate 下的元素中附加我的专用宽度大小来解决它,即在您的情况下为 />,会根据你的绑定[REF]元素调整内容宽度。曾经没有尝试过“Horizo​​ntalAlignment”和“Horizo​​nalTextAlgent”对我有用。 【参考方案1】:

尝试使用TextAlignment 属性而不是HorizontalAlignment - 应该这样做。 据我了解,HorizontalAlignment="Center" 将使您的文本块居中,而不是其中的文本。

【讨论】:

这是我第一次尝试时使用的。它也不起作用。很抱歉没有把它放在我最初的帖子中。 你左手还是右手时有用吗?检查此链接,看看您是否可以发现与您的 xaml 的差异 --> social.msdn.microsoft.com/forums/en-US/wpf/thread/…【参考方案2】:

这可能是一个很长的镜头,但我不得不为项目由模板定义的列表框做这件事。尝试在 ListView 上设置 Horizo​​ntalContentAlignment="Stretch"。如果我没有设置这些项目只占用他们需要的空间并且左对齐。

【讨论】:

【参考方案3】:

我创建了一个适用于以下常见场景的解决方案:

<GridViewColumn Header="Some Property" DisplayMemberBinding="Binding SomeProperty" />

人们只想要一个简单的DisplayMemberBinding 文本,而不必指定CellTemplate

新代码使用附加属性并变为:

<GridViewColumn Header="Some Property" DisplayMemberBinding="Binding SomeProperty" 
                ctrl:GridViewExtensions.IsContentCentered="True" />

附加属性代码:

public static class GridViewExtensions

    #region IsContentCentered

    [Category("Common")]
    [AttachedPropertyBrowsableForType(typeof(GridViewColumn))]
    public static bool GetIsContentCentered(GridViewColumn gridViewColumn)
    
        return (bool)gridViewColumn.GetValue(IsContentCenteredProperty);
    
    public static void SetIsContentCentered(GridViewColumn gridViewColumn, bool value)
    
        gridViewColumn.SetValue(IsContentCenteredProperty, value);
    

    public static readonly DependencyProperty IsContentCenteredProperty = 
        DependencyProperty.RegisterAttached(
            "IsContentCentered",
            typeof(bool), // type
            typeof(GridViewExtensions), // containing type
            new PropertyMetadata(default(bool), OnIsContentCenteredChanged)
            );

    private static void OnIsContentCenteredChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    
        OnIsContentCenteredChanged((GridViewColumn)d, (bool)e.NewValue);
    
    private static void OnIsContentCenteredChanged(GridViewColumn gridViewColumn, bool isContentCentered)
    
        if (isContentCentered == false)  return; 
        // must wait a bit otherwise GridViewColumn.DisplayMemberBinding will not yet be initialized, 
        new DispatcherTimer(TimeSpan.FromMilliseconds(100), DispatcherPriority.Normal, OnColumnLoaded, gridViewColumn.Dispatcher)
        
            Tag = gridViewColumn
        .Start();
    

    static void OnColumnLoaded(object sender, EventArgs e)
    
        var timer = (DispatcherTimer)sender;
        timer.Stop();

        var gridViewColumn = (GridViewColumn)timer.Tag;
        if (gridViewColumn.DisplayMemberBinding == null)
        
            throw new Exception("Only allowed with DisplayMemberBinding.");
        
        var textBlockFactory = new FrameworkElementFactory(typeof(TextBlock));
        textBlockFactory.SetBinding(TextBlock.TextProperty, gridViewColumn.DisplayMemberBinding);
        textBlockFactory.SetValue(TextBlock.TextAlignmentProperty, TextAlignment.Center);
        var cellTemplate = new DataTemplate  VisualTree = textBlockFactory ;
        gridViewColumn.DisplayMemberBinding = null; // must null, otherwise CellTemplate won't be recognized
        gridViewColumn.CellTemplate = cellTemplate;
    

    #endregion IsContentCentered

【讨论】:

请注意,我没有彻底测试 DispatcherTimer 区间,所以你可能想弄乱它。 另外,请注意我的解决方案不考虑对值的更改。 (即如果 IsContentCentered 值从 true 更改为 false,则绑定不会恢复为左对齐)【参考方案4】:

这是我展示工作 xaml 的示例:

<Window x:Class="WPF_Tutorial.Rich_text_controls.BlockUIContainerCenteredColumnSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        xmlns:self="clr-namespace:WPF_Tutorial.Rich_text_controls"
        Title="BlockUIContainerCenteredColumnSample" Height="275" Width="300"
        WindowStartupLocation="CenterScreen">
    <Window.Resources>
        <x:Array x:Key="UserArray" Type="x:Type self:User">
            <self:User Name="John Doe" Age="42" />
            <self:User Name="Jane May-Anne Josephine Renalds Doe" Age="36" />
        </x:Array>
    </Window.Resources>
    <Grid>
        <FlowDocumentScrollViewer>
            <FlowDocument>
                <Paragraph FontSize="36" Margin="0">Users</Paragraph>
                <Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">Here's a list of our users, inside our FlowDocument, in a completely interactive ListView control!</Paragraph>
                <BlockUIContainer>
                    <ListView BorderThickness="0" ItemsSource="StaticResource UserArray" HorizontalAlignment="Center">
                        <ListView.ItemContainerStyle>
                            <Style TargetType="ListViewItem">
                                <!-- This stretches out the TextBlock width to the column width -->
                                <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                            </Style>
                        </ListView.ItemContainerStyle>
                        <ListView.View>
                            <GridView>
                                <GridViewColumn Header="Name" DisplayMemberBinding="Binding Name" Width="150" />
                                <GridViewColumn>
                                    <GridViewColumnHeader Content="Age" Width="75" />
                                    <GridViewColumn.CellTemplate>
                                        <DataTemplate>
                                            <TextBlock Text="Binding Age" TextAlignment="Center" />
                                        </DataTemplate>
                                    </GridViewColumn.CellTemplate>
                                </GridViewColumn>
                            </GridView>
                        </ListView.View>
                    </ListView>
                </BlockUIContainer>
                <Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">More content can go here...</Paragraph>
            </FlowDocument>
        </FlowDocumentScrollViewer>
    </Grid>
</Window>

注意&lt;ListView.ItemContainerStyle&gt; 块。它有&lt;Setter ...。 没有这个,根据 AndyG 的文字,任何事情都不会按照你想要的方式工作。

尝试解决这个问题非常令人沮丧。

顺便说一下,这里是这个 xaml 的支持代码:

namespace WPF_Tutorial.Rich_text_controls

    using System.Windows;

    public partial class BlockUIContainerCenteredColumnSample : Window
    
        public BlockUIContainerCenteredColumnSample()
        
            InitializeComponent();
        
    

    public class User
    
        public int Age  get; set; 

        public string Name  get; set; 
    


What you should see when run

【讨论】:

以上是关于WPF - 如何在 ListView 中居中列数据?的主要内容,如果未能解决你的问题,请参考以下文章

WPF - 如何在 WrapPanel 中居中所有项目?

在 Column Flutter 中居中展开 ListView

在ListView中居中布局

请问 WPF中如何动态改变 ListView中 某一个值 颜色。

Flutter - 如何在列表视图中居中小部件

WPF如何获得ListView内各单元格控件