WPF工具提示不会更新

假设我有一个代表工作人员的简单类

class Staff { public string FirstName { get; set; } public string FamilyName { get; set; } public int SecondsAlive { get; set; } } 

我有一个DataTemplate供员工使用

           

然后我在ListBox中展示了一大堆人员

 myListBox.ItemsSource = GetAllStaff(); 

很标准的东西。 我遇到的问题是显示某人活着的秒数的工具提示没有得到更新。 当你第一次将鼠标移到一个工作人员上时,它工作正常,但从那时起它就永远保持这个价值。 我可以实现INotifyPropertyChanged以解决这个问题,但是只要SecondsAlive发生变化,每个工作人员都可以做到这一点。 假设我在列表中有400名员工,那么我必须筹集400个事件,即使用户可能永远不会查看另一个工具提示。 我想要的是使工具提示请求显示SecondsAlive属性。 那可能吗?

请注意,这只是一个例子,我不需要知道我的员工活了多少秒:-)但我有同样的问题,我需要提高一个甚至大约400倍的工具提示,有人可能不会看。

我的天啊!!! 我终于找到了解决这个问题的方法! 这几个月一直困扰着我。 我并不感到惊讶没有人回答这个,因为我在顶部输入的代码实际上并没有显示我试图重现的问题,实际上它显示了解决方案。 答案是,如果您定义这样的工具提示

     

然后一切正常,花花公子,没有必要在“SecondsAlive”上提出propertyChanged事件。 每次显示工具提示时,框架都会调用SecondsAlive属性。 当你定义你的工具提示时,问题出现了:

       

在那里有额外的工具提示标记是有道理的,当然你需要创建一个工具提示对象来将其分配给tooltip属性,但这是不正确的。 您分配给tooltip属性的实际上是工具提示的内容 。 我假设您需要为其显示文本块和图像等控件,但您可以传入任何内容,它将像内容控件一样显示内容。 看到它从内容控制inheritance这是有道理的:-)一旦你知道这一切似乎很明显:-)

谢谢大家看这个。

PS。 我发现了一个额外的问题,即简化代码的下一个逻辑步骤是将文本直接分配给工具提示,如下所示(假设您的工具提示是纯文本):

   

这也导致我遇到的原始问题。 这是有道理的,因为属性StaffToolTip的结果被分配给tooltip属性,永远不会再被调用。 但是,为什么然后将textBlock分配给tooltip属性实际上解决了问题并不是很有意义。

在这种特殊情况下,你可以使用一个很酷的技巧

Seconds Alive Now = Seconds Alive最初+ Elapsed Time

您可以绑定到Elapsed Time属性并指定一个向其添加初始值的转换器。 这样你只需要引发1个事件,工具提示就会全部更新。

编辑:您可以将ElapsedTime属性(使用INotifyPropertyChanged)添加到许多位置 – 一个逻辑位置可以是存储您的Staff对象的集合

编辑:您还需要将每个工具提示绑定到共享的ElapsedTime属性而不是SecondsAlive属性

值得注意的是,在使用新数据重新加载自身之前,工具提示似乎检查您的对象是否必须相等。

在我的情况下,我做了一个覆盖

 public override bool Equals(object obj) 

 public override int GetHashCode() 

在具有属性的类上

 public class MultipleNameObject { string Name, string[] OtherNames}; 

Unfortunatley我只在MultipleNameObject的Name属性上做了一个string.Compare(),用于相等的目的。 工具提示应该在ItemsControl中显示OtherNames,但如果在鼠标hover在网格上的前一个MultipleNameObject上名称相等,则不会更新,即使OtherNames不同。

[edit]运行启用调试确认ToolTip正在使用我的对象的GetHashCode()重写来决定是否重新获取新数据。 修复了将字符串[] OtherNames考虑在内的问题。

此示例显示如何在网格中添加工具提示,以便在用户将鼠标hover在网格中的单元格上时按需重新计算工具提示。

如果您有一个包含10,000个项目的巨大网格,并且您希望连续更新网格 – 但您不想连续更新工具提示,这很有用,因为这非常耗时。

此示例适用于Infragistics,但该原则同样适用于其他精细库,如DevExpress。

XAML

                      

视图模型

 public ICommand ToolTipHoverRefreshCommand => new DelegateCommand(() => { this.OnPropertyChanged(this.ToolTip); }); public string ToolTip { get { return DateTime.Now.ToString(); } set { this.OnPropertyChanged(nameof(this.ToolTip)); } }