如何在带有绑定的TextBlock中实现NullText?

时间:2011-04-09 01:17:47

标签: c# wpf

我想为绑定到ViewModel中的属性的TextBlock实现“NullText”行为。当ViewModel中的该属性为null或为空时,我想显示类似“ No Data ”的灰色斜体文本。我希望这能遵循MVVM模式,但我迷失了......

更新 因此,在使用James Webster建议的解决方案之后,我让它像这样工作......

<UserControl.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
    <c:NullOrEmptyValueConverter x:Key="NullOrEmptyValueConverter" Text="(No Data)"/>
</UserControl.Resources>

 ...     

<TextBlock Name="SerialNumberTextBlock" Text="{Binding Path=SerialNumber, Converter={StaticResource NullOrEmptyValueConverter}}">
    <TextBlock.Resources>
        <Style TargetType="TextBlock">
            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=SerialNumberTextBlock, Path=Text}" Value="(No Data)">
                    <Setter Property="FontStyle" Value="Italic"/>
               </DataTrigger>
           </Style.Triggers>
        </Style>
    </TextBlock.Resources>
</TextBlock>

4 个答案:

答案 0 :(得分:5)

我建议实施IValueConverter;如果源值不为null或为空,则将其传递给TextBlock。如果源值为null或为空,则呈现所选文本。

public class NullValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        string str = (string)value;
        if (str.IsNullOrWhitespace())
        {
            return "No Data";
        }
        return str;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        ... //An empty implementation I expect...
    }
}

但是我刚刚意识到你想要设置样式......嗯,可能是一个DataTrigger,如果我想要的值是“无数据”,则设置样式;

<TextBlock Text="{Binding Path=SomeProperty, Converter={StaticResource keyToNullValueConverter}">
    <TextBlock.Triggers>
        <DataTrigger Binding="{Binding Path=Text}" Value="No Data">
            <Setter Property="FontStyle" Value="Italic"/>
        </DataTrigger>
    </TextBlock.Triggers>
</TextBlock>

这些方面的某些内容可能有用。

答案 1 :(得分:2)

我认为你不需要创建Converter Class,你可以简单地编写你的样式代码。

<Style TargetType="TextBlock">             
<Style.Triggers>                 
<DataTrigger Binding="{Binding ElementName=SerialNumberTextBlock, Path=Text}" Value="{x:Null}">                     
<Setter Property="FontStyle" Value="Italic"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=SerialNumberTextBlock, Path=Text}" Value="{x:Static System:String.Empty}">                     
<Setter Property="FontStyle" Value="Italic"/>
</DataTrigger>
</Style.Triggers>         
</Style> 

注意: - 您需要将系统命名空间包含为

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

答案 2 :(得分:0)

您可以尝试绑定到看起来如此的属性

    private string _textBlockText;
    public string TextBlockText
    {
        get
        {
            if(string.IsNullOrEmpty(_textBlockText))
            {
                return "No Data";
            }
            return _textBlockText;
        }
        set
        {
            _textBlockText = value;
        }
    }

然后使用James提到的XAML样式。节省了转换器的需求。

答案 3 :(得分:0)

晚会很晚,但这是我的答案。

<TextBox >
    <TextBox.Style>
        <Style TargetType="{x:Type TextBox}">
            <Setter Property="Text" Value="{Binding MyText, TargetNullValue=No data}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding MyText}" Value="{x:Null}">
                    <Setter Property="FontStyle" Value="Italic"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding MyText}" Value="{x:Static System:String.Empty}">
                    <Setter Property="FontStyle" Value="Italic"/>
                </DataTrigger>
                <Trigger Property="IsFocused" Value="True">
                    <Setter Property="Text" Value="{Binding MyText}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>

我的答案假设您希望默认文本在焦点上消失,这更符合默认文本输入通常的行为。同样,这仅适用于空值。如果您需要检查字符串为空或其他逻辑,则可以像其他提供的答案一样使用转换器。关键思想是,当控件获得焦点时,请在绑定中删除空值文本或转换器,从而仅当控件没有焦点时才显示默认文本。这也可以防止默认值流回您的视图模型。

有关字体样式的DataTriggers部分是从pchajer的答案中借来的。