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

时间:2009-11-01 17:20:53

标签: wpf xaml listview alignment

我还在学习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,但是像这样的一些简单的事情似乎真的很难。

4 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

这可能是一个很长的镜头,但我必须为列表框执行此操作,其中项目由模板定义。尝试在ListView上设置Horizo​​ntalContentAlignment =“Stretch”。如果我没有设置这些项目只占用他们需要的空间并保持合理。

答案 2 :(得分:0)

我已经创建了一个在以下常见情况下工作的解决方案:

<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

}

答案 3 :(得分:0)

这是我的示例来展示一个有效的 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>

注意 <ListView.ItemContainerStyle> 块。它有 <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