我想为绑定到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>
答案 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的答案中借来的。