我有一個 StackPanel,里面有幾個 TextBlock,像這樣:
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="First is quite lengthy" />
<TextBlock Text="This one's shorter"/>
<TextBlock Text="This one too"/>
<TextBlock Text="This one is a bit longer again"/>
</StackPanel>
我想證明所有這些都是合理的,以便 TextBlocks 的左側和右側都垂直對齊 - 我該怎么做?
上面的代碼如下所示:

粗略估計我想要實作的目標:

我曾嘗試嘗試使用 TextAlignment(Justify 對我不起作用)、FontStretch、Horizo??ntalAlignment、DockPanel 和 Viewbox(由于我想保持字體大小不變,因此不起作用)。我可以做些什么來實作這一點,而無需對文本內的某些空格進行硬編碼?
uj5u.com熱心網友回復:
我很驚訝地發現 WPF 默認不支持對齊的單行 TextBlocks。但是,您可以相對輕松地自己實作此行為。我拼湊了一個快速解決方案,該解決方案提供了一個 UserControl,其單一目的是繪制對齊的單行文本。
解決方案非常簡單,不支持文本換行、邊距或任何其他特殊布局情況,并且只有基本的 DependencyProperties。不過,這應該是一個很好的起點。
public partial class JustifiedLine : UserControl
{
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text",
typeof(string),
typeof(JustifiedLine),
new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty MinSpaceWidthProperty = DependencyProperty.Register(
"MinSpaceWidth",
typeof(double),
typeof(JustifiedLine),
new FrameworkPropertyMetadata(5.0, FrameworkPropertyMetadataOptions.AffectsRender));
public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public double MinSpaceWidth
{
get => (double)GetValue(MinSpaceWidthProperty);
set => SetValue(MinSpaceWidthProperty, value);
}
public JustifiedLine()
{
InitializeComponent();
}
protected override void OnRender(DrawingContext drawingContext)
{
string[] words = Text.Split(' ');
if (words.Length == 0)
return;
int numValidWords = 0;
double totalWordsWidth = 0;
/* add widths of all words */
for (int i = 0; i < words.Length; i )
{
if (String.IsNullOrWhiteSpace(words[i]))
continue;
FormattedText fText = MakeFormattedText(words[i]);
totalWordsWidth = fText.Width;
numValidWords ;
}
double fullWidth = GetFullWidth();
double spaceWidth = (fullWidth - totalWordsWidth) / (numValidWords - 1);
if (spaceWidth < MinSpaceWidth)
spaceWidth = MinSpaceWidth;
double currentWidth = 0;
for (int i = 0; i < words.Length; i )
{
if (String.IsNullOrWhiteSpace(words[i]))
continue;
FormattedText fText = MakeFormattedText(words[i]);
drawingContext.DrawText(fText, new Point(currentWidth, 0));
currentWidth = fText.Width spaceWidth;
/* if Height isn't specified, automatically set from text height */
if (double.IsNaN(Height))
Height = fText.Height;
}
}
/* return either width of this control, or the parent control if not set. If neither is set, return 0.0 */
private double GetFullWidth()
{
if (!double.IsNaN(Width))
return Width;
FrameworkElement parent = Parent as FrameworkElement;
if (parent != null && !double.IsNaN(parent.ActualWidth))
return parent.ActualWidth;
return 0.0;
}
/* might want to bind font etc. to dependency property, these here are just placeholders */
private FormattedText MakeFormattedText(string text)
{
return new FormattedText(
text,
CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight,
new Typeface("Verdana"),
16,
Brushes.White,
VisualTreeHelper.GetDpi(this).PixelsPerDip);
}
}
如果這樣使用:
<StackPanel Width="300">
<usercontrols:JustifiedLine Text="First is quite lengthy"/>
<usercontrols:JustifiedLine Text="This one's shorter"/>
<usercontrols:JustifiedLine Text="This one too"/>
<usercontrols:JustifiedLine Text="This one is a bit longer again"/>
</StackPanel>
xmlns:usercontrols="clr-namespace:MyProject.controls.usercontrols"
這是我的結果:

uj5u.com熱心網友回復:
我不會撒謊,不久前我第一次拿起 WPF,所以如果我的回答沒有完全提供最佳解決方案,我深表歉意。無論如何,我認為您唯一的選擇是將不同的單詞作為不同的文本塊并使用邊距和對齊設定。否則,據我所知,我可能誤解了這個問題。對不起,如果我有。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/357656.html
上一篇:ComboBox是重點更改邊框
下一篇:WPF系結資料模板
