我有一个大型应用程序,它有很多工具提示。工具提示显示不断变化的数据快照。目前,我通过轮询,然后设置属性并遵循INotifyPropertyChanged模式来重新计算数据的快照。这样做有效,但结果是用户可能会注意到如果数据不幸则数据尚未刷新。此外,该应用程序浪费了大量资源来计算可能永远不会使用的数据快照,因为工具提示没有提出。
这是一个示例应用来证明这一点:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:WpfApplication2"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<l:ViewModel />
</Window.DataContext>
<Grid>
<Button Content="Test"
ToolTip="{Binding ElapsedTime}" />
</Grid>
</Window>
使用ViewModel:
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
StartTime = DateTime.Now;
}
public DateTime StartTime { get; set; }
public double ElapsedTime { get { return (DateTime.Now - StartTime).TotalSeconds; } }
protected void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
所以,我的问题是,而不是让一些线程更新&#34; ElapsedTime&#34;在用户需要工具提示的情况下,每秒都有一个属性,XAML中是否有办法说如果需要绑定的值,请务必阅读它吗?
答案 0 :(得分:1)
更好的方法是使用MouseEnter
附加行为并在鼠标悬停时更新ElapsedTime
。
<强> ViewModel.cs 强>
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
StartTime = DateTime.Now;
UpdateTime = new RelayCommand( UpdateElapsedTime, new Func<bool>(() => { return true; }));
}
public DateTime StartTime { get; set; }
private double _elapsedTime;
public double ElapsedTime
{
get { return _elapsedTime; }
set { _elapsedTime = value; RaisePropertyChanged("ElapsedTime"); }
}
public ICommand UpdateTime { get; set; }
private void UpdateElapsedTime()
{
ElapsedTime = (DateTime.Now - StartTime).TotalSeconds;
}
protected void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
<强> MouseEnterBehavior.cs 强>
public static class MouseEnterBehavior
{
public static readonly DependencyProperty MouseEnterProperty =
DependencyProperty.RegisterAttached("MouseEnter",
typeof(ICommand),
typeof(MouseEnterBehavior),
new PropertyMetadata(null, MouseEnterChanged));
public static ICommand GetMouseEnter(DependencyObject obj)
{
return (ICommand)obj.GetValue(MouseEnterProperty);
}
public static void SetMouseEnter(DependencyObject obj, ICommand value)
{
obj.SetValue(MouseEnterProperty, value);
}
private static void MouseEnterChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
UIElement uiElement = obj as UIElement;
if (uiElement != null)
uiElement.MouseEnter += new MouseEventHandler(uiElement_MouseEnter);
}
static void uiElement_MouseEnter(object sender, MouseEventArgs e)
{
UIElement uiElement = sender as UIElement;
if (uiElement != null)
{
ICommand command = GetMouseEnter(uiElement);
command.Execute(uiElement);
}
}
}
<强> XAML 强>
<Button Content="Test"
ToolTip="{Binding ElapsedTime}" local:MouseEnterBehavior.MouseEnter ="{Binding UpdateTime}"/>
MouseEnterBehavior的参考: How can I execute a command binding on MouseEnter of a StackPanel in WPF?
答案 1 :(得分:0)
触发指示更改的事件。
处理此事件以重置您的DataContext
,
SomeControl.DataContext = null;
SomeControl.DataContext = oldObject; // re-assign your object again