WPF工具提示条件语句

5

我在一个网格中有一个Textblock,它有一个ToolTip,应该显示"tooltip"绑定,但如果它是NullEmpty,则应显示"name"绑定。

如何在XAML中实现这一点?

<TextBlock Margin="3" TextAlignment="Left" VerticalAlignment="Center" FontSize="12" Foreground="Black" HorizontalAlignment="Left" ToolTip="{Binding Tooltip, FallbackValue='name'}" Text="{Binding Name}"/>


XAML用于显示而非逻辑,如果需要逻辑应该放在视图模型中,不过可以使用PriorityBinding或MultiBinding。 - MikeT
4个回答

4

您可以使用一个或两个DataTriggersStyle,只有在Tooltip源属性返回null或空string时,将ToolTip属性绑定到Name源属性:

<TextBlock Margin="3" TextAlignment="Left" VerticalAlignment="Center" FontSize="12" Foreground="Black" HorizontalAlignment="Left" 
                   Text="{Binding Name}">
    <TextBlock.Style>
        <Style TargetType="TextBlock">
            <Setter Property="ToolTip" Value="{Binding Tooltip}" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding Tooltip}" Value="{x:Null}">
                    <Setter Property="ToolTip" Value="{Binding Name}" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Tooltip}" Value="">
                    <Setter Property="ToolTip" Value="{Binding Name}" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

2
如果字符串为NULL 创建MultiValueConverter并将其声明为静态资源:
<local:MyConverter x:Key="MyConverter"/>

您的转换器类应该长这样:
public class MyConverter: IMultiValueConverter
{
   public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
   {
        string tooltip = values.ElementAtOrDefault(0) as string,
           name = values.ElementAtOrDefault(1) as string;
        if(!String.IsNullOrEmpty(tooltip))            
            return tooltip;            
        else            
            return name;                        
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
 }

并且您的文本块:

<TextBlock FontSize="12" Foreground="Red" Text="{Binding MyName}">
      <TextBlock.ToolTip>
           <MultiBinding Converter="{StaticResource NameConverter}">
               <Binding Path="Tooltip" IsAsync="True"/>
               <Binding Path="MyName"/>
           </MultiBinding>
      </TextBlock.ToolTip>
</TextBlock>

无法按照他想要的方式绑定多个值,因此需要使用MultiBinding或PriorityBinding。 - MikeT
我想只显示一个提示 - 如果“tooltip”绑定值为空,则显示“name”绑定值...不需要多重绑定。 - Ram
@MaiurLaximidas 当值为空时,您想要显示什么名称? - tabby
如果这两个字符串都为空,则不需要显示任何内容。 - Ram
@MaiurLaximidas,您希望将其绑定到工具提示和名称,然后根据值选择要显示的内容。 - MikeT
如果“Tooltip”有值,则显示它,否则显示“name”的任何内容,即使它为空。 - Ram

2
来自MSDN
在Windows Presentation Foundation (WPF)中,PriorityBinding通过指定一系列绑定来工作。这些绑定按照从高到低的优先级顺序排列。如果处理最高优先级绑定时成功返回值,则无需处理列表中的其他绑定。可能情况是,最高优先级绑定需要很长时间才能被评估,在此期间成功返回值的下一个优先级绑定将被使用,直到更高优先级的绑定成功返回值。
例如,代码如下:
<StackPanel>
    <ToggleButton IsChecked="{Binding ShowTooltip, Mode=TwoWay}" >toggle</ToggleButton>
    <TextBlock>
        <TextBlock.ToolTip>
            <PriorityBinding>
                <Binding Path="ToolTipSometimes" Mode="OneWay"/>
                <Binding Path="Name" Mode="OneWay"/>
            </PriorityBinding>
        </TextBlock.ToolTip>
    </TextBlock>
</StackPanel>

如果 A 绑定成功返回一个值,则满足以下条件:

  • 绑定源的路径成功解析。

  • 如果有,值转换器能够转换结果值。

  • 生成的值对于目标属性是有效的。

使用 MultiBinding 可以像这样完成:

<TextBlock >
    <TextBlock.ToolTip>
        <MultiBinding>
            <MultiBinding.Converter>
                <local:NullCleanup/>
            </MultiBinding.Converter>
            <Binding Path="ToolTip" Mode="OneWay"/>
            <Binding Path="Text" Mode="OneWay" />
        </MultiBinding>
    </TextBlock.ToolTip>
</TextBlock>

使用这个作为转换器

public class NullCleanup : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return values.Aggregate((r, o) => r ?? o);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

然而,您可以将逻辑放在虚拟机中。

    private string _Tooltip;

    public string Tooltip;
    {
        get { return _Tooltip; }
        set { SetProperty(ref _Tooltip, value,()=>RaisePropertyChanged(nameof(ToolTipCleaned))); }
    }

    public string ToolTipCleaned => Tooltip ?? Name;

不太符合我的预期...什么决定了一个值是否成功返回?我的要求是:如果第一个绑定返回 null,则检查第二个绑定并显示它,即使该值为 null。 - Ram
我希望有类似于ToolTip="{Binding Tooltip ?? Binding Name}"的东西。 - Ram
XAML代表可扩展应用程序标记语言,因此它与HTML属于同一类别,不包括像ASP、Razor或PHP这样的预处理。 - MikeT

1
我通过以下方式使用TooltipOpening实现了这一点:
<TextBlock Margin="3" TextAlignment="Left" VerticalAlignment="Center" FontSize="12" Foreground="Black" HorizontalAlignment="Left" ToolTip="" ToolTipOpening="TextBlock_ToolTipOpening"  Text="{Binding Name}" TextWrapping="Wrap" MaxWidth="470" />

然后在“TextBlock_ToolTipOpening”方法中,我按照以下方式应用了我的检查:

    if (!String.IsNullOrEmpty(stf.Tooltip))
    {
       t.ToolTip = stf.Tooltip;
    }
    else
    {
        t.ToolTip = stf.Name;
    }

它按照预期工作-感谢大家的贡献...没有你们的帮助我不会解决这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接