【问题标题】:Add colon at the end of the text or right aligned depending on the value of RowSpan of a textblock根据文本块的 RowSpan 值在文本末尾添加冒号或右对齐
【发布时间】:2013-12-29 19:48:31
【问题描述】:

我有一个如下代码中提到的文本块:

<TextBlock Grid.Row=........
           .................
           Grid.RowSpan="{Binding RowSp}"
           HorizontalAlignment="Left" />

现在我想检查是否RowSpan &gt; 1 然后我想在文本末尾添加一个空格和一个冒号。我认为(未尝试)我已经使用触发器和转换器得到它如下代码中所述:

<TextBlock.Style>
    <Style TargetType="TextBlock">
        <Style.Triggers>
            <Trigger Property="{Binding RowSp, 
                                Converter={StaticResource colonAlignmentConverter}}" 
                     Value="True" >
                <Setter Property="Text" 
                        Value="{Binding Txt, 
                                Converter=ColonAlignmentConverter}" />
            </Trigger>
        </Style.Triggers>
    </Style>
</TextBlock.Style>

public class ColonAlignmentConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return (int)value > 1;
    }

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

现在问题来了:

如果RowSpan = 1 那么我想在同一个 Grid.Row 和 Grid.Column 中添加冒号(:) 但我想要它right aligned。我怎样才能做到这一点?

如果可能的话,我可以使用另一个文本块作为冒号。

【问题讨论】:

    标签: wpf xaml


    【解决方案1】:

    这通常使用模板来完成,但正如您所知,您不能模板化 TextBlock。

    但是,当您将字符串传递给 ContentControl 的 Content 属性时,ContentControl 使用 TextBlock 来显示字符串。这是通过使用 Snoop 发现的,这是一个很棒的 WPF 调试工具。

    考虑到这一点,Grid.RowSpan 对于 Grid 的任何子项的默认值为 1,并且您希望在 TextBlock 的 RowSpan 大于 1 时显示冒号,以下将执行你想要的。

    <Window x:Class="StackOverflow._20820850.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
        <Style x:Key="TextBlockContentControlStyle" TargetType="{x:Type ContentControl}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ContentControl">
                        <Grid>
                            <TextBlock Text="{TemplateBinding Content}" />
                            <TextBlock Text=":" HorizontalAlignment="Right"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="Grid.RowSpan" Value="1">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ContentControl">
                                <Grid>
                                    <TextBlock Text="{TemplateBinding Content}" />
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
    
        <ContentControl Content="One" Style="{StaticResource TextBlockContentControlStyle}" />
        <ContentControl Content="Two" Grid.Column="1" Grid.RowSpan="2" Style="{StaticResource TextBlockContentControlStyle}" />
        </Grid>
    </Window>
    

    注意事项

    1. 我已将 TextBlock 替换为 ContentControl(我不确定您是否可以使用此选项)
    2. 我想使用纯 XAML 方法,因此我的默认模板是管理 RowSpan > 1 的模板。然后我提供一个触发器将模板设置回默认 RowSpan = 1。
    3. 这需要是键控样式,因为将其设置为默认样式可能会破坏在其逻辑树或可视树中使用 ContentControl 的所有其他控件。

    如果您不想使用 ContentControl,另一种方法是创建您自己的 UserControl。在下文中,我创建了一个名为 MyTextBlock 的控件(我可以将其命名为 TextBlock 并让命名空间对其进行排序,但在示例中这更清楚),然后我将控件的内容模板化。用户控件的 XAML 是

    <UserControl x:Name="ThisControl" x:Class="StackOverflow._20820850.MyTextBlock" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300">
        <UserControl.ContentTemplate>
            <DataTemplate>
                <Grid DataContext="{Binding ElementName=ThisControl}">
                    <TextBlock Text="{Binding Path=Content}" />
                    <TextBlock Text=":" HorizontalAlignment="Right">
                        <TextBlock.Style>
                            <Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type TextBlock}}">
                                <Setter Property="Visibility" Value="Visible" />
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding (Grid.RowSpan)}" Value="1">
                                        <Setter Property="Visibility" Value="Collapsed" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBlock.Style>
                    </TextBlock>
                </Grid>
            </DataTemplate>
        </UserControl.ContentTemplate>
    </UserControl>
    

    Window 中的网格现在看起来像

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
    
        <this:MyTextBlock Content="One" />
        <this:MyTextBlock Content="Two" Grid.Column="1" Grid.RowSpan="2" />
    </Grid>
    

    显然,冒号可能会被忽略,因为它被推到控件的右侧,但我将把格式留给你。

    我希望这会有所帮助。

    【讨论】:

    • 谢谢。它按预期工作。我遵循了您使用 ContentControl 的第一种方法,因为我没有在我的应用程序中使用 ContentControl。我对您创建的样式进行了一些更改,并将其添加到应用程序资源中。现在它可以在没有任何方法的情况下正常工作。再次感谢。
    • 太棒了。我很高兴它成功了。我仍然会键入 ContentControl,因为控件可以在内部使用 ContentControl,并且除非键入,否则您的样式也将应用于这些控件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 2013-04-05
    • 2013-07-05
    • 1970-01-01
    相关资源
    最近更新 更多