繁体   English   中英

Wpf TextBlock 中的垂直文本

[英]Vertical Text in Wpf TextBlock

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

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

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

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

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

以防万一还有人看到这篇文章...这是一个简单的 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>

我认为在不改变系统固有的文本布局方式的情况下,没有一种直接的方法可以做到这一点。 最简单的解决方案是更改文本块的宽度并提供一些额外的属性,如下所示:

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

这是 hacky,但它确实有效。

只需使用一个简单的 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>

这是可行的:

您的TextBlockTextAlignment属性应设置为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从原始字符串中的各个字符创建一个字符串数组。我相信还有其他方法可以做到这一点......)

下面的 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>

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

拉入 mscorlib

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

放入您的用户控件/窗口/页面资源

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

并像这样使用它

<ItemsControl ItemsSource="{Binding Source={StaticResource SortString}}" Margin="5,-1,0,0"   />    

希望能帮助到你!

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

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

创建一个堆栈面板,其中包含一堆占用一个字符的文本块

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

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

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

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

下面是在 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 提出的,但我相信我的实施会产生更少的开销。

您还可以使用“RUN”绑定

在 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创建绑定到文本块的命令

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
电子
r

一世
C
一种



电子
X

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

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

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

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'}"/>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM