在我的程序中,我有一组视图模型对象来表示ListBox中的项目(允许多选)。视图模型有一个IsSelected属性,我希望将其绑定到ListBox上,以便选择状态在视图模型中管理,而不是在ListBox本身中管理。
然而,显然ListBox不会维护大多数屏幕外的项目的绑定,因此通常情况下IsSelected属性无法正确同步。以下是一些演示问题的代码。首先是XAML:
然而,显然ListBox不会维护大多数屏幕外的项目的绑定,因此通常情况下IsSelected属性无法正确同步。以下是一些演示问题的代码。首先是XAML:
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock>Number of selected items: </TextBlock>
<TextBlock Text="{Binding NumItemsSelected}"/>
</StackPanel>
<ListBox ItemsSource="{Binding Items}" Height="200" SelectionMode="Extended">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<Button Name="TestSelectAll" Click="TestSelectAll_Click">Select all</Button>
</StackPanel>
C# 全选处理程序:
private void TestSelectAll_Click(object sender, RoutedEventArgs e)
{
foreach (var item in _dataContext.Items)
item.IsSelected = true;
}
C#视图模型:
public class TestItem : NPCHelper
{
TestDataContext _c;
string _text;
public TestItem(TestDataContext c, string text) { _c = c; _text = text; }
public override string ToString() { return _text; }
bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set {
_isSelected = value;
FirePropertyChanged("IsSelected");
_c.FirePropertyChanged("NumItemsSelected");
}
}
}
public class TestDataContext : NPCHelper
{
public TestDataContext()
{
for (int i = 0; i < 200; i++)
_items.Add(new TestItem(this, i.ToString()));
}
ObservableCollection<TestItem> _items = new ObservableCollection<TestItem>();
public ObservableCollection<TestItem> Items { get { return _items; } }
public int NumItemsSelected { get { return _items.Where(it => it.IsSelected).Count(); } }
}
public class NPCHelper : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void FirePropertyChanged(string prop)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
可以观察到两个单独的问题。
- 如果您点击第一个项目,然后按Shift + End,应选择所有200个项目;然而,标题报告仅选择了21个项目。
- 如果您点击“全选”则确实选择了所有项目。如果您随后点击 ListBox 中的一个项目,则预期其它199个项目将被取消选择,但实际上并没有发生这种情况。相反,只有屏幕上显示的项目(以及一些其他项目)会被取消选择。除非您从头到尾滚动列表(即使使用小的滚动框进行滚动也无效),否则不会取消选择所有199个项目。
我的问题是:
- 有人能够准确解释为什么会出现这种情况吗?
- 我能够避免或解决这个问题吗?