我在列表框中对齐字符串内容时遇到问题。这是一个演示我的应用程序所遇问题的简单示例:
基本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的下拉建议中,那么这也会起作用,因为这最终是目标。
答案 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
。但无论如何,这是一种有趣的技巧,不应该用于重要的商业应用程序。