【问题标题】:Can't binding in ToolTip无法在 ToolTip 中绑定
【发布时间】:2021-10-12 12:34:28
【问题描述】:

我正在使用 WPF C# 中的ToolTip。我想将元素属性绑定到ToolTip 内容,但输出为空。最初,我使用了下面的绑定,但它不起作用。

Content="{Binding ElementName=txtf1, Path=Text}"

于是我在这里找到了相关的解决方案,但结果并没有改变。谁能指出我哪里出错了?

<StackPanel Height="Auto" Margin="15,10,15,0" Width="74">
    <Image Source="/Image/AutoCAD.png" Width="50"/>
    <TextBlock x:Name="txtf1" Text="Border19072021 Border19072021"/>
    <StackPanel.ToolTip>
        <ToolTip DataContext="{Binding Path=PlacementTarget.DataContext , 
                              RelativeSource={RelativeSource Self}}">
            <Label Content="{Binding ElementName=txtf1, Path=Text}"/>
        </ToolTip>
     </StackPanel.ToolTip>
</StackPanel>

【问题讨论】:

  • 您对"{Binding Path = PlacementTarget.DataContext... 绑定有什么期望? StackPanel 数据上下文?
  • @EldHasp 我在这里引用,stackoverflow.com/questions/53312073/…(...允许工具提示引用其他控件的一种方法是劫持此放置目标控件的一些其他未使用的属性(标记通常是合适的) , 然后可以被工具提示引用...)

标签: c# wpf xaml data-binding tooltip


【解决方案1】:

[...] 最初,我使用Content="{Binding ElementName=txtf1, Path=Text}",但它不起作用。

是的,这是因为 WPF 中的每个窗口都有自己的可视化树,其中包含元素和 ToolTip,其他弹出窗口实际上显示在单独的窗口中。 ElementName 绑定在这里不起作用(RelativeSource 也是),因为它们是不同的 XAML namescopes

您引用的问题是正确的方法,但您以错误的方式应用它。理论上你可以使用DataContext属性作为ToolTip的绑定间接,但你不应该

<StackPanel DataContext="{Binding Text, ElementName=txtf1}" Height="Auto" Margin="15,10,15,0" Width="74">
   <Image Source="/Image/AutoCAD.png" Width="50"/>
   <TextBlock x:Name="txtf1" Text="Border19072021 Border19072021"/>
   <StackPanel.ToolTip>
      <ToolTip DataContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
         <Label Content="{Binding}"/>
      </ToolTip>
   </StackPanel.ToolTip>
</StackPanel>

上述代码有效,但DataContext 属性在 WPF 中用于数据绑定的核心目的。不要为此目的滥用此属性,否则您会破坏可视树中的数据绑定。除此之外,Label ToolTip 上的绑定是多余的,如下所示。还有一个名为Tag 的属性,您可以为其分配任何值。

获取或设置可用于存储有关此元素的自定义信息的任意对象值。

<StackPanel Tag="{Binding Text, ElementName=txtf1}" Height="Auto" Margin="15,10,15,0" Width="74">
   <Image Source="/Image/AutoCAD.png" Width="50"/>
   <TextBlock x:Name="txtf1" Text="Border19072021 Border19072021"/>
   <StackPanel.ToolTip>
      <ToolTip>
         <Label Content="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType={x:Type ToolTip}}}"/>
      </ToolTip>
   </StackPanel.ToolTip>
</StackPanel>

您可以使用RelativeSource 绑定直接从标签中引用ToolTip.Tag。如果有多个这样的绑定,您可以考虑为每个绑定创建自定义 attached properties 并以相同的方式绑定它们。

【讨论】:

    【解决方案2】:

    我在这里参考,How to binding other element in ToolTip

    您没有仔细阅读您所指的主题。

    ToolTip、ContextMenu、Popup(和其他一些元素)会弹出窗口的内容而不更改它。
    自己想一想:如何在不更改此 Window 的可视化树的情况下将新元素引入 Window?
    答:这不能以任何方式完成。

    因此,这些弹出元素被实现为显示在主窗口(调用它们的窗口)上方的新小窗口的内容。
    由于这些是不同的窗口,因此它们具有不同的视觉树。
    因此,无法从弹出窗口的树中的主窗口中找到元素(ElementName 和 FindAncestor 类型的绑定)。

    您可以使用元素引用(Binding Sourse = {x: Reference ...}),因为引用是在编译时解析的,而不考虑可视化树。

    例子:

        <StackPanel Height="Auto" Margin="15,10,15,0" Width="74">
            <Image Source="/Image/AutoCAD.png" Width="50"/>
            <TextBlock x:Name="txtf1" Text="Border19072021 Border19072021"/>
            <StackPanel.ToolTip>
                <ToolTip>
                    <Label Content="{Binding Source={x:Reference txtf1}, Path=Text}"/>
                </ToolTip>
             </StackPanel.ToolTip>
        </StackPanel>
    

    此外,Popup 的 DataContext 继承自创建它的元素。
    在您的情况下,这是来自 StackPanel。
    因此,您可以简单地设置默认的 Bindings 来接收数据。

    例子:

        <StackPanel Height="Auto" Margin="15,10,15,0" Width="74">
            <Image Source="/Image/AutoCAD.png" Width="50"/>
            <TextBlock x:Name="txtf1" Text="{Binding SomeViewModelProperty}"/>
            <StackPanel.ToolTip>
                <ToolTip>
                    <Label Content="{Binding SomeViewModelProperty}"/>
                </ToolTip>
             </StackPanel.ToolTip>
        </StackPanel>
    

    PlacementTarget 属性用于更改弹出窗口的目标元素。
    DataContext 继承自该元素。
    如果未指定,则从指定浮出控件的元素继承 DataContext。
    你没有指定它,所以它是 null,这是你的绑定返回的。

    例子:

    <StackPanel DataContext="{Binding Text, ElementName=txtf1}" Height="Auto" Margin="15,10,15,0" Width="74">
       <Image Source="/Image/AutoCAD.png" Width="50"/>
       <TextBlock x:Name="txtf1" Text="{Binding SomeViewModelProperty}"/>
       <StackPanel.ToolTip>
          <ToolTip  PlacementTarget="{Binding ElementName=txtf1}"
                    DataContext="{Binding Path=PlacementTarget.DataContext,
                                          RelativeSource={RelativeSource Self}}">
             <Label Content="{Binding SomeViewModelProperty}"/>
          </ToolTip>
       </StackPanel.ToolTip>
    </StackPanel>
    

    【讨论】:

      猜你喜欢
      • 2020-09-14
      • 1970-01-01
      • 1970-01-01
      • 2011-04-09
      • 2018-04-04
      • 1970-01-01
      • 2017-02-23
      • 2010-12-16
      • 2012-05-15
      相关资源
      最近更新 更多