我们有像这样的ItemsControl设置
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Items}" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Data}"></TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
使用MainViewModel:
public class MainViewModel : ViewModelBase
{
public ObservableCollection<AutoUpdatingItem> Items
{
get;
set;
}
public MainViewModel()
{
Items = new ObservableCollection<AutoUpdatingItem>();
for (int i = 0; i < 1000; i++)
{
Items.Add(new AutoUpdatingItem(i));
}
}
}
和行的ViewModel
public class AutoUpdatingItem : ViewModelBase
{
private readonly DispatcherTimer timer;
private int data;
public int Data
{
get { return data; }
set { Set(ref data, value); }
}
public AutoUpdatingItem(int i)
{
Data = i;
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(20);
timer.Start();
timer.Tick += Timer_Tick;
}
private void Timer_Tick(object sender, EventArgs e)
{
// Data would be fetched from WebService here
Data++;
}
}
我们如何才能实现只有可见项目的更新?有什么方法可以在回收虚拟化面板中的项目时收到通知吗?
答案 0 :(得分:0)
这可能有用(参见:In WPF, how can I determine whether a control is visible to the user?):
public class AutoUpdatingItem : INotifyPropertyChanged
{
private readonly DispatcherTimer timer;
private int data;
public int Data
{
get { return data; }
set
{
data = value;
propertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Data)));
}
}
public AutoUpdatingItem()
{
timer = new DispatcherTimer(new TimeSpan(0,0,0,0,200), DispatcherPriority.Background, Tick, Dispatcher.CurrentDispatcher);
timer.Stop();
}
private void Tick(object sender, EventArgs e)
{
Data++;
}
private event PropertyChangedEventHandler propertyChanged;
public event PropertyChangedEventHandler PropertyChanged
{
add
{
propertyChanged += value;
timer.Start();
}
remove
{
timer.Stop();
propertyChanged -= value;
}
}
}
使用以下XAML:
<ItemsControl ItemsSource="{Binding Items}"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling" Height="500">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Data}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate>
<Border >
<ScrollViewer VerticalScrollBarVisibility="Visible"
CanContentScroll="True">
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>