0

经过相当多的搜索和阅读其他问题和帖子后,我无法找到如何解决这个问题。注意:我对 WPF 比较陌生(一般不绑定)。

这就是我所追求的:

  1. 我想让窗口中的所有 TextBlock 控件以某种方式设置样式。
  2. 该样式还应应用 ValueConverter 以使文本全部大写。
  3. 最后,每个 TextBlock 文本可以来自绑定到视图模型属性,也可以来自绑定到 .resx 文件中的资源字符串

这是我正在玩的摘录:

<!-- in Window resources -->
<help:AllCapsStringConverter x:Key="AllCaps"/>

<Style TargetType="TextBlock">
    <Setter Property="Foreground" Value="Brown" />
    <Setter Property="Text">
        <Setter.Value>
            <Binding>
                <Binding.Converter>
                    <help:AllCapsStringConverter />
                </Binding.Converter>
                <!-- also tried adding:
                <Binding.RelativeSource>
                    <RelativeSource Mode="Self" />
                </Binding.RelativeSource>
                -->
            </Binding>

            <!-- also tried with: 
            <Binding Converter="{StaticResource AllCaps}"/>

            <Binding Path="Text" Converter="{StaticResource AllCaps}"/>
            -->
        </Setter.Value>
    </Setter>
</Style>

<!-- in Window content -->
<TextBlock Text="{x:Static resx:MyResources.MyTitle}" />

这是价值转换器,它本身已被证明是有效的:

class AllCapsStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null && value is string)
        {
            return ((string)value).ToUpper();
        }
        else
        {
            return value;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}

TextBlocks 获得前景色,但没有转换。

我能够将转换器本地应用于单个 TextBlock,但我不想将其应用于窗口周围的所有 TextBlock:

<TextBlock>
    <TextBlock.Text>
        <Binding Source="{x:Static resx:MyResources.MyTitle}"
                 Converter="{StaticResource AllCaps}"/>
    </TextBlock.Text>
</TextBlock>
<!-- which is the same as -->
<TextBlock Style="{StaticResource CustomerInfoTitleStyle}" 
           Text="{Binding Source={x:Static resx:MyResources.MyTitle}, Converter={StaticResource AllCaps}}" />
4

2 回答 2

2

您的转换器无法正常工作,因为您TextBlock正在覆盖 的Text属性Style,其中包括您添加到绑定中的转换器。

例如:

<Grid.Resources>

    <Style x:Key="MyTextBlockStyle" TargetType="TextBlock">
        <Setter Property="Foreground" Value="Red"/>
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="Text" Value="You won't see this."></Setter>
    </Style>

</Grid.Resources>

<TextBlock Text="You will see this." Style="{StaticResource MyTextBlockStyle}"/>

希望从上面你可以看到为什么你的方法不起作用。

更好的解决方案是Text使用值转换器在 上TextBlock而不是在上设置 的值Style

如果您不想这样做,您可以用来解决此问题的一种常见作弊方法是将 TextBlock 的 Text 属性绑定到 Tag 属性,如下所示:

<Grid.Resources>

    <local:AllCapsConverter x:Key="AllCaps"/>

    <Style x:Key="MyTextBlockStyle" TargetType="TextBlock">
        <Setter Property="Foreground" Value="Red"/>
        <Setter Property="FontSize" Value="16"/>
        <Setter Property="Text" Value="{Binding Tag, RelativeSource={RelativeSource Self}, Converter={StaticResource AllCaps}}"/>
    </Style>

</Grid.Resources>

<TextBlock Tag="You will see this." Style="{StaticResource MyTextBlockStyle}"/>

我非常不喜欢这种方法,但它确实可以得到你想要的。我希望你在设置绑定时只使用转换器TextBlock

lukegv 的方法是另一种选择。但是,不需要使用Label,因为您正在覆盖模板并且(类似于我上面的示例)您只是绑定ContentLabel. 您可以轻松地从ContentControl.

<Grid.Resources>

    <local:AllCapsConverter x:Key="AllCaps"/>

    <Style x:Key="MyContentControl" TargetType="ContentControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <TextBlock Text="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource AllCaps}}"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</Grid.Resources>

<ContentControl Style="{StaticResource MyContentControl}" Content="You will see this too!"/>

不过,我也不是这个想法的特别忠实拥护者,因为您无法访问所有其他TextBlock属性。例如,如果我想设置FontWeightmy 的属性,TextBlock那么我会被塞满。

于 2015-01-21T15:07:39.410 回答
0

尝试使用“标签”并构建模板,因为“文本块”不是控件

<Style x:Key="AllCapsLabel" TargetType="{x:Type Label}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Label">
                <TextBlock Foreground="Brown" Text="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource AllCaps}}" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

并以这种方式使用它:

<Label Style="{StaticResource AllCapsLabel}" Content="whatever you want" />

如果内容是纯文本(又名“字符串”),则文本应始终为大写。

于 2015-01-21T14:05:03.120 回答