【发布时间】:2011-10-02 11:43:15
【问题描述】:
假设我有一个代表员工的简单类
class Staff
{
public string FirstName { get; set; }
public string FamilyName { get; set; }
public int SecondsAlive { get; set; }
}
我有一个员工数据模板
<DataTemplate DataType={x:Type Staff}>
<StackPanel Orientation="Horizontal">
<TextBlock Text={Binding FirstName}/>
<TextBlock Text=" ">
<TextBlock Text={Binding FamilyName}/>
<StackPanel.ToolTip>
<TextBlock Text={Binding SecondsAlive}/>
</StackPanel.ToolTip>
</StackPanel>
</DataTemplate>
然后我在 ListBox 中显示一大堆员工
myListBox.ItemsSource = GetAllStaff();
相当标准的东西。我遇到的问题是显示某人还活着的秒数的工具提示没有得到更新。当您第一次将鼠标悬停在工作人员上时,它可以正常工作,但从那时起,它会永远保持该值。我可以实施 INotifyPropertyChanged 来解决这个问题,但是每当 SecondsAlive 发生变化时,对每个员工都这样做似乎有点过头了。假设列表中有 400 名员工,那么即使用户可能永远不会查看另一个工具提示,我也必须引发 400 个事件。我想要的是让工具提示每次显示时都请求 SecondsAlive 属性。这可能吗?
请注意,这只是一个示例,我不需要知道我的员工已经活了多少秒 :-) 但我有同样的问题,我需要为工具提示提出 400 次左右可能有人不会看。
【问题讨论】:
-
您是否真的测试过这种情况(引发 400 个事件),并且在实施 INotifyPropertyChanged 时事件发生了 400 次?如果是这样,您可以使用虚拟化堆栈面板,因此并非所有 Staff 对象都被实例化(并因此绑定)
-
在我的例子中,每个工作人员都由屏幕上的一个小框表示,并且他们都始终可见。
-
提高 400 个事件是我现在正在做的事情。我们目前无法调试绑定(显然是下一个版本)所以我不知道结果是什么。
-
速度不一定是问题。请记住,我的 SecondsAlive 只是一个示例,我说的是工具提示的一般情况。如果有大量更新每次引发 400 个事件,这可能是一个问题。部分问题是我需要编写的代码量。例如,在我的应用程序的一个地方,我有一个包含大约 30 个属性的人员对象,并且我添加了一个基于这 30 个属性中的许多属性的工具提示属性。对于工作人员的每个属性,我还需要为工具提示引发一个 propertychanged 事件。这对我来说似乎很麻烦。
-
如果我每次都能获得工具提示来调用绑定,这将使应用程序中许多地方的一切变得更加简单。我做了一些测试,它看起来像在某些情况下创建了一个新的工具提示对象,但在其他情况下它被重用了。奇怪的是,它必须将结果缓存在工具提示对象之外的某个地方,因为即使创建了新的工具提示对象,它也会保留旧值(如果未引发属性更改)。我只需要获取工具提示即可丢弃此缓存。