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

时间:2015-10-22 19:16:57

标签: wpf vb.net string-formatting

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

基本XAML用户界面:

<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

输出: output

这就是我实际想要完成的事情(糟糕的油漆编辑,但基本上我只想让列对齐,无论客户名称的长度如何): desiredOutput

根据我的阅读,String.Format应该做我想要的,但输出永远不对。我也尝试对每个字符串(名称,ID,dob和电话)使用String.PadRight但是行为相同(列错位)。

我忽略了一些简单的事情吗?

编辑:我实际应用中的控件不是ListBox。它是来自WPF Toolkit的AutoCompleteBox。我使用上面的ListBox作为示例,因为它表现出格式化字符串的相同行为,并且更容易用一个简单的例子。

如果有人知道如何将列添加到AutoCompleteBox的下拉建议中,那么这也会起作用,因为这最终是目标。

2 个答案:

答案 0 :(得分:1)

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

设置像Consolas这样的固定宽度字体(每个字符的宽度都以像素为单位)将解决问题。

然而,固定宽度字体看起来不是很令人愉快,更好的解决方案是使用一个“知道”的控件。什么是&#39;多列&#39;手段。 (ListView,DataGrid)

答案 1 :(得分:1)

对于想要显示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 foreach数据项(一个字符串)。模板应该是ItemsControl,以显示自定义ItemsPanelTemplate中的字符列表,以水平堆叠这些字符(以便以可读文本的形式连接)。由于每个字符都是Border具有固定宽度,因此可以使用为Border(及其Margin)设置了适当宽度的任何字体。对于包装文字,我们可能需要使用WrapPanel。但无论如何,这是一种有趣的技巧,不应该用于重要的商业应用程序。

enter image description here