我會保持簡潔。我有一個實現ItemTemplate的ListBox。 DataTemplate包含一個複選框。我加載了大約2000個項目。我檢查前5項,滾動到底部並選擇最後5項。然後我滾動到頂部的項目,並注意到我的前5個檢查項目已被修改。ItemsControl中項目的渲染問題
<Window
x:Class="CheckItems.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CheckItems"
Title="Window1" Height="300" Width="300"
>
<DockPanel>
<StackPanel DockPanel.Dock="Bottom" >
<Button Content="Test" Click="Button_Click"/>
</StackPanel>
<ListBox DockPanel.Dock="Left"
x:Name="users"
ItemsSource="{Binding Path=Users}"
>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox>
<TextBlock Text="{Binding Path=Name}"/>
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</Window>
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
namespace CheckItems
{
public partial class Window1 : Window
{
ViewModel controller;
public Window1()
{
DataContext = controller = new ViewModel();
InitializeComponent();
controller.Users = LoadData();
}
private List<User> LoadData()
{
var newList = new List<User>();
for (var i = 0; i < 2000; ++i)
newList.Add(new User { Name = "Name" + i, Age = 100 + i });
return newList;
}
private void Button_Click(object sender, RoutedEventArgs e)
{ }
}
public class User
{
public string Name { get; set; }
public int Age { get; set; }
}
public class ViewModel : INotifyPropertyChanged
{
private List<User> users;
public event PropertyChangedEventHandler PropertyChanged;
public List<User> Users
{
get { return users; }
set { users = value; NotifyChange("Users"); }
}
protected void NotifyChange(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
希望對此有一個很好的解釋 - 這是一個MS錯誤。這發生在.NET 3.5和4.0中。當VirtualingStackPanel.IsVirtualizing設置爲false時,不會發生此行爲,但在真實世界中,無虛擬化加載是痛苦的。
有些洞察力會很好。
由於提前,
安德烈奧利瓦雷斯
謝謝你的解釋Rachel。至於你的建議,我真的不喜歡它是一種可接受的模式,將屬性放在描述UI上的行爲的模型上。我明白這個建議非常受歡迎,但我不認爲這是一個合理的解決方案。 根據你提供的解釋,我寧願更喜歡一個解決方案,在滾動期間丟失DataContext不會丟失或恢復。 我會發布更多關於這種努力,這應該更多地解釋我的困境,但非常感謝您的關注。 – 2012-01-05 19:42:44
@AndresOlivares你可以創建一個包含IsSelected和User對象屬性的類,然後在ViewModel中創建這些對象的List,而不是使用List List。我過去使用的另一種選擇是將'IsChecked'綁定到'ListBoxItem.IsSelected'屬性,允許ListBox選擇多個項目,並隱藏ListBox的選擇功能。這隻會在你不使用選擇功能的時候起作用。 –
Rachel
2012-01-05 20:04:31