我正在尝试学习ObservableCollection<T>
和ListBox的VirtualizingStackPanel
。
MyTestData
类中有一个图像,绑定到Image
内的ListBox.ItemTemplate
(缩略图属性)。问题是,当我滚动时,Thumbnail
属性被调用两次。这是一个问题还是WPF如何运作?
窗口:
<Window x:ClassModifier="internal" x:Class="Virtual.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" SizeToContent="Height" Width="525" WindowStartupLocation="CenterScreen">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical">
<Button x:Name="btnAdd1" Content="Add 1" Click="btnAdd_Click"></Button>
<Button x:Name="btnAdd10" Content="Add 10" Click="btnAdd_Click"></Button>
<Button x:Name="btnAdd100" Content="Add 100" Click="btnAdd_Click"></Button>
<Button x:Name="btnAdd1000" Content="Add 1000" Click="btnAdd_Click"></Button>
<Button x:Name="btnAdd1000000" Content="Add 1.000.000" Click="btnAdd_Click"></Button>
<TextBox x:Name="tbDebug" Margin="0,10,0,25" Height="250" AcceptsReturn="True">
</TextBox>
</StackPanel>
<Button x:Name="btnAdd" Content="Add" VerticalAlignment="Bottom" Click="btnAdd_Click"></Button>
<ListBox x:Name="lbList2" Margin="10,0,0,25" Height="350"
Grid.Column="1"
ScrollViewer.CanContentScroll="True"
ScrollViewer.IsDeferredScrollingEnabled="False"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel></VirtualizingStackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Border Margin="3,0,0,0" BorderBrush="Black" BorderThickness="1">
<Image VerticalAlignment="Top" HorizontalAlignment="Left" MaxWidth="30" MaxHeight="30" SnapsToDevicePixels="True" Source="{Binding Thumbnail, UpdateSourceTrigger=PropertyChanged}" />
</Border>
<Label Content="{Binding Name}"></Label>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button x:Name="btnAdd2" Margin="10,0,0,0" Grid.Column="1" Content="Add" VerticalAlignment="Bottom" Click="btnAdd_Click"></Button>
</Grid>
</Window>
代码:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Virtual
{
internal class MyTestData
{
public string Name { get; set; }
private BitmapSource _thumbnail = null;
public BitmapSource Thumbnail
{
get
{
if (_thumbnail == null)
_thumbnail = new BitmapImage(new Uri("c:\\300.jpg"));
Console.Text += "\n" + Name + " --> THUMBNAIL";
Console.ScrollToEnd();
return _thumbnail;
}
}
public MyTestData(string oName)
{
Name = oName;
}
internal TextBox Console;
}
internal partial class MainWindow : Window
{
public List<string> OItems1 { get; set; }
public ObservableCollection<MyTestData> OItems2 { get; set; }
public MainWindow()
{
InitializeComponent();
OItems1 = new List<string>();
OItems2 = new ObservableCollection<MyTestData>();
lbList2.ItemsSource = OItems2;
}
private void OAdd(int c)
{
for (int i = 0; i < c; i++)
{
OItems2.Add(new MyTestData("oDATA = " + (OItems2.Count + 1).ToString())
{
Console = tbDebug
});
}
}
private void btnAdd_Click(object sender, RoutedEventArgs e)
{
if (sender == btnAdd1)
OAdd(1);
else if (sender == btnAdd10)
OAdd(10);
else if (sender == btnAdd100)
OAdd(100);
else if (sender == btnAdd1000)
OAdd(1000);
else if (sender == btnAdd1000000)
OAdd(1000000);
}
}
}
答案 0 :(得分:1)
这是一个问题还是WPF如何运作?
后者。请参阅Microsoft在Connect上的以下答案:
框架(或任何其他人)有权以任何理由随意调用属性获取者。不能保证它只会被调用一次。
意外行为:绑定引擎获取ImageSource两次: https://connect.microsoft.com/VisualStudio/feedback/details/770169/unexpected-behaviour-binding-engine-getting-imagesource-twice
所以这种行为是预期的。