Wpf TextBlock中的垂直文本

时间:2008-12-08 15:34:32

标签: c# wpf

是否可以垂直显示TextBlock中的文本,以便所有字母相互堆叠(不使用LayoutTransform旋转)?

16 个答案:

答案 0 :(得分:72)

还没有人提到使用纯XAML垂直堆叠任意字符串的字母(不旋转它们)的明显而简单的方法:

<ItemsControl
  ItemsSource="Text goes here, or you could use a binding to a string" />

这通过识别字符串是IEnumerable的事实来简单地垂直布局文本,因此ItemsControl可以将字符串中的每个字符视为单独的项目。 ItemsControl的默认面板是StackPanel,因此字符是垂直布局的。

注意:为了精确控制水平定位,垂直间距等,可以在ItemsControl上设置ItemContainerStyle和ItemTemplate属性。

答案 1 :(得分:22)

以防任何人仍然遇到这篇文章......这是一个简单的100%xaml解决方案。

    <TabControl TabStripPlacement="Left">
        <TabItem Header="Tab 1">
            <TabItem.LayoutTransform>
                <RotateTransform Angle="-90"></RotateTransform>      
            </TabItem.LayoutTransform>
            <TextBlock> Some Text for tab 1</TextBlock>
        </TabItem>
        <TabItem Header="Tab 2">
            <TabItem.LayoutTransform>
                <RotateTransform Angle="-90"></RotateTransform>
            </TabItem.LayoutTransform>
            <TextBlock> Some Text for tab 2</TextBlock>
        </TabItem>
    </TabControl>

答案 2 :(得分:18)

我认为,通过改变系统固有的文本方式来实现这一目标并不是一件好事。最简单的解决方案是更改文本块的宽度并提供一些额外的属性,如下所示:

<TextBlock TextAlignment="Center" FontSize="14" FontWeight="Bold" Width="10" TextWrapping="Wrap">THIS IS A TEST</TextBlock>

这很麻烦,但确实有效。

答案 3 :(得分:11)

只需使用简单的LayoutTransform ..

<Label Grid.Column="0" Content="Your Text Here" HorizontalContentAlignment="Center">
  <Label.LayoutTransform>
    <TransformGroup>
        <RotateTransform Angle="90" />
        <ScaleTransform ScaleX="-1" ScaleY="-1"/>
    </TransformGroup>
  </Label.LayoutTransform>
</Label>

答案 4 :(得分:4)

这是可行的:

您的TextBlock TextAlignment媒体资源应设为Center

<TextBlock Name="textBlock1" TextAlignment="Center" Text="Stacked!" />

然后在每个字符之间添加NewLine

textBlock1.Text =
    String.Join(
        Environment.NewLine,
        textBlock1.Text.Select(c => new String(c, 1)).ToArray());

(使用System.Linq从原始字符串中的各个字符创建一个字符串数组。我确信还有其他方法可以做到这一点......)

答案 5 :(得分:2)

Ray Burns建议的答案在.net 4.0上对我不起作用。我是这样做的:

拉入mscorlib

xmlns:s="clr-namespace:System;assembly=mscorlib"

输入你的usercontrol / window / page资源

<s:String x:Key="SortString">Sort</s:String>

并像这样使用

<ItemsControl ItemsSource="{Binding Source={StaticResource SortString}}" Margin="5,-1,0,0"   />    
希望它有所帮助!

答案 6 :(得分:2)

XAML代码下方更改文本块中显示的文本角度。

<TextBlock Height="14"
        x:Name="TextBlock1"
        Text="Vertical Bottom to Up" Margin="73,0,115,0" RenderTransformOrigin="0.5,0.5" >
        <TextBlock.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform Angle="-90"/>
                <TranslateTransform/>
            </TransformGroup>
        </TextBlock.RenderTransform>
 </TextBlock>

答案 7 :(得分:1)

使用一堆带有一个char的文本块创建一个stackpanel

答案 8 :(得分:1)

使文本容器的最大宽度仅允许一个字符并包装文本:

<TextBlock TextWrapping="Wrap" MaxWidth="8" TextAlignment="Center" Text="stack" />

答案 9 :(得分:1)

制作图像并用图像填充块,使用photoshop或设计用于操作文本而不是摆弄代码的东西?

答案 10 :(得分:1)

此代码允许使用垂直文本堆叠和水平居中字母。

<ItemsControl Grid.Row="1"
              Grid.Column="0"
              ItemsSource="YOUR TEXT HERE"
              HorizontalAlignment="Center"
              VerticalAlignment="Center">

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}"
                   HorizontalAlignment="Center"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ItemsControl>

答案 11 :(得分:0)

这是一种在TextBlock文本中的每个字符后插入'\ n'的方法,这样就可以使它垂直显示:

<TextBlock x:Name="VertTextBlock" Text="Vertical Text" Loaded="VertTextBlock_Loaded"></TextBlock>

然后,在Loaded事件处理程序中,您说:

TextBlock tb = sender as TextBlock;
StringBuilder sb = new StringBuilder(tb.Text);
int len = tb.Text.Length * 2;

for (int i = 1; i < len; i += 2)
{
    sb.Insert(i, '\n');
}

tb.Text = sb.ToString();

这个解决方案是由Lette提出的,但我相信我的实现会产生更少的开销。

答案 12 :(得分:0)

<linebreak/> can be used to show data in two lines

答案 13 :(得分:0)

您还可以使用“运行”绑定

在App.xaml文件中,使用类似以下的内容:

<Application x:Class="Some.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:commands="clr-namespace:Deridiam.Helper.Commands"
         xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
         ShutdownMode="OnMainWindowClose"
         StartupUri="Views/MainWindow.xaml">
<Application.Resources>

    <commands:HorizontalToVertical x:Key="HorizontalToVertical_Command"></commands:HorizontalToVertical>

    <ControlTemplate x:Key="VerticalCell" TargetType="ContentControl">
            <TextBlock Text="{TemplateBinding Content}" Foreground="Black"
                    TextAlignment="Center" FontWeight="Bold" VerticalAlignment="Center"
                    TextWrapping="Wrap" Margin="0" FontSize="10">  
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Loaded">
                        <i:InvokeCommandAction Command="{Binding ConvertToVerticalCmd, Source={StaticResource HorizontalToVertical_Command}}" 
                                               CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type TextBlock}}}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </TextBlock>
    </ControlTemplate>

</Application.Resources>

在app.xaml示例中的 Loaded 事件上,使用 i:Interaction.Triggers 创建 command 类,该类绑定到文本块。 >

namespace Deridiam.Helper.Commands
{
public class HorizontalToVertical
{
    private ICommand _convertToVerticalCommand;

    public ICommand ConvertToVerticalCmd =>
        _convertToVerticalCommand ?? (_convertToVerticalCommand = new RelayCommand(
                x =>
                {
                    var tBlock = x as TextBlock;
                    var horizontalText = tBlock.Text;
                    tBlock.Text = "";

                    horizontalText.Select(c => c).ToList().ForEach(c =>
                    {
                        if (c.ToString() == " ")
                        {
                            tBlock.Inlines.Add("\n");
                            //tBlock.Inlines.Add("\n");
                        }

                        else
                        {
                            tBlock.Inlines.Add((new Run(c.ToString())));
                            tBlock.Inlines.Add(new LineBreak());
                        }


                    });
                }));
}
}

最后在.xaml文件中,您希望在其中显示垂直文本

<ContentControl Width="15" Content="Vertical Text" Template="{StaticResource VerticalCell}">
</ContentControl>

将导致:

V
e
r
t
i
c
a
l

T
e
x
t

答案 14 :(得分:0)

上述解决方案都没有解决我的问题(有些解决方案很接近),所以我在这里发布我的解决方案,也许可以帮助某人。 接受的解决方案对我有帮助,但文本未与中心对齐。

<ItemsControl ItemsSource="{Binding SomeStringProperty, FallbackValue=Group 1}" Margin="5"
          TextElement.FontSize="16" 
          TextElement.FontWeight="Bold" 
          TextBlock.TextAlignment="Center"
          HorizontalAlignment="Center" 
          VerticalAlignment="Center" >
<ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
        <WrapPanel Orientation="Vertical" />
    </ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
    <DataTemplate  >
        <TextBlock Text="{Binding }" HorizontalAlignment="Center"  />
    </DataTemplate>
</ItemsControl.ItemTemplate>

答案 15 :(得分:-2)

我将提供基于转换器的解决方案:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;

namespace Converters
{
    [ValueConversion(typeof(object), typeof(string))]
    public class InsertLineBreakConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (parameter != null)
                value = parameter;

            if (value == null)
                return null;

            if (!(value is string str))
                str = value.ToString();

            return string.Join(Environment.NewLine, (IEnumerable<char>) str);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        public static InsertLineBreakConverter Instance { get; } = new InsertLineBreakConverter();
    }

    public class InsertLineBreakConverterExtension : MarkupExtension
    {
        public override object ProvideValue(IServiceProvider serviceProvider)
            => InsertLineBreakConverter.Instance;
    }
}

使用示例:

   <TextBlock Text="{Binding Property, Converter={cnvs:InsertLineBreakConverter}}"/>   
   <TextBlock Text="{Binding Converter={cnvs:InsertLineBreakConverter}, ConverterParameter='Some Text'}"/>