如何对齐列表框中的字符串内容文本?

How to align string contents text in a listbox?

我在对齐列表框中的字符串内容时遇到问题。这是一个演示我的应用程序遇到的问题的提炼示例:

基本XAMLUI:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="687" Loaded="Window_Loaded">
    <Grid>
        <ListBox x:Name="lstClients" HorizontalAlignment="Left" Height="220" Margin="28,22,0,0" VerticalAlignment="Top" Width="625"/>
    </Grid>
</Window>

后面的代码:

Class MainWindow
    Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)
        Dim names() As String = {"Cook, Adam", "Renolds, Bridgette", "Smith, Carla", "Doe, Daniel",
                                "Redmond, Ebenezer", "Kelly, Francine"}
        Dim ids() As String = {"123456", "654321", "112345", "274587", "128493", "937401"}
        Dim dob() As String = {"1/2/80", "4/17/88", "8/31/72", "6/11/91", "10/27/81", "3/3/75"}
        Dim phones() As String = {"1234567890", "2536772364", "1537779004", "7586712164", "8548778384", "0987654321"}

        For i As Integer = 0 To 5
            lstClients.Items.Add(FormatClientString(names(i), ids(i), dob(i), phones(i)))
        Next
    End Sub

    Private Function FormatClientString(name As String, id As String, birthDate As String, phone As String)
        Dim clientString As String
        clientString = String.Format("{0, -52} {1, -17} {2, -20} {3}", name, id, birthDate, phone)
        Return clientString
    End Function
End Class

输出:

这就是我实际想要完成的(蹩脚的绘画编辑,但基本上我只想让列对齐,不管客户姓名的长度如何):

根据我的阅读,String.Format should do what I want, but the output is never right. I also tried using String.PadRight 每个字符串(名称、ID、出生日期和电话)但得到相同的行为(未对齐的列)。

我是不是忽略了一些简单的东西?

编辑:我的实际应用程序中的控件不是列表框。它是来自 WPF Toolkit 的自动完成框。我使用上面的 ListBox 作为示例,因为它展示了格式化字符串的相同行为,并且更容易制作一个简单的示例。

如果有人知道如何向 AutoCompleteBox 的下拉建议中添加列,那也行,因为这就是最终目标。

问题是由您的控件使用的字体引起的。它是一种比例字体,因此您不能使用空格来创建特定宽度的列来填充列,因为每行的文本部分的像素长度不同。

设置像 Consolas 这样的固定宽度字体(其中每个字符的像素宽度相同)将解决此问题。

然而,固定宽度的字体看起来不太舒服,更好的解决方案是使用 'knows' 'multi columns' 表示的控件。 (列表视图、数据网格)

对于那些想用比例字体显示 string.Format 的人,试试这个 XAML(这只是 的乐趣,但可能会用在一些不需要太多样式灵活性的简单应用程序中)。使用此代码,我们可能需要根据所选字体调整固定 Width

<ListBox x:Name="lstClients" HorizontalAlignment="Left" Height="220" Margin="28,22,0,0" 
         VerticalAlignment="Top" Width="625" FontFamily="Lucida Calligraphy">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <ItemsControl ItemsSource="{Binding}">                        
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Border Width="20" Margin="0,0,-12,0">
                                <TextBlock Text="{Binding}" TextAlignment="Center"/>
                            </Border>                                
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Horizontal"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                </ItemsControl>
            </DataTemplate>
        </ListBox.ItemTemplate>
</ListBox>

这里的想法是每个字符串都是一个字符数组。所以我们为每个数据项(一个字符串)定义了一个ItemTemplate。模板应该是 ItemsControl 以显示自定义 ItemsPanelTemplate 中的字符列表,以水平堆叠这些字符(加入可读文本)。因为每个字符都是一个具有固定宽度的 Border,所以它可以与为 Border(及其 Margin)设置适当宽度的任何字体一起使用。对于换行文本,我们可能需要使用 WrapPanel 来代替。但无论如何,这是一种有趣的把戏,不应该在重要的商业应用程序中使用。