【问题标题】:How to align string contents text in a listbox?如何对齐列表框中的字符串内容文本?
【发布时间】:2015-10-22 19:16:56
【问题描述】:

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

基本 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

输出:

这就是我真正想要完成的事情(糟糕的绘画编辑,但基本上我只想让列对齐,不管客户姓名的长度如何):

根据我的阅读,String.Format 应该做我想做的事,但输出永远不会正确。我还尝试对每个字符串(姓名、id、dob 和电话)使用 String.PadRight,但得到了相同的行为(未对齐的列)。

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

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

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

【问题讨论】:

  • 等宽​​字体的每个字母和空格的宽度不同。但是你为什么不改用 ListView 呢?
  • @Steve 实际上,它是来自WPF Toolkit 的AutoCompleteBox,但未对齐行为在ListBox 中是相同的(我使用List(Of String) 作为AutoCompleteBox 的ItemsSource)。
  • 正如我所说的。问题是由您的控件使用的字体引起的。它是一种比例字体,因此您无法使用空格创建特定宽度的列来填充缺失的字符。尝试设置一个固定宽度的字体,如 Consolas,你会看到不同之处。简单的解决方案是使用“知道”“多列”含义的控件。
  • 我删除了我的回答,因为你更新了问题
  • @Steve 你成功了。我将其更改为 Consolas 并且有效。将此作为答案提交,我会标记它。

标签: wpf vb.net string-formatting


【解决方案1】:

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

设置像 Consolas 这样的固定宽度字体(每个字符都具有相同的像素宽度)可以解决问题。

但是,固定宽度的字体看起来不太好,更好的解决方案是使用“知道”“多列”含义的控件。 (列表视图、数据网格)

【讨论】:

    【解决方案2】:

    对于那些想用比例字体显示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 来代替。但无论如何,这是一种有趣的技巧,不应该在重要的商业应用中使用。

    【讨论】:

      猜你喜欢
      • 2014-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-14
      • 2013-04-21
      • 2020-11-28
      相关资源
      最近更新 更多