Qwe*_*tie 8 .net wpf binding listbox mvvm
在我的程序中,我有一组视图模型对象来表示ListBox中的项目(允许多选).viewmodel有一个IsSelected属性,我想绑定到ListBox,以便在viewmodel而不是列表框本身中管理选择状态.
但是,显然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>
Run Code Online (Sandbox Code Playgroud)
C#Select All处理程序:
private void TestSelectAll_Click(object sender, RoutedEventArgs e)
{
foreach (var item in _dataContext.Items)
item.IsSelected = true;
}
Run Code Online (Sandbox Code Playgroud)
C#viewmodel:
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));
}
}
Run Code Online (Sandbox Code Playgroud)
可以观察到两个独立的问题.
我的问题是:
dle*_*lev 11
ListBox默认情况下,UI是虚拟化的.这意味着在任何给定时刻,ItemsSource实际上只会呈现遗嘱中的可见项目(以及"几乎可见"项目的一小部分).这解释了为什么更新源按预期工作(因为这些项始终存在),但只是导航UI不会(因为这些项的可视化表示是动态创建和销毁的,并且不会同时存在.)
如果要关闭此行为,一个选项是设置ScrollViewer.CanContentScroll=False您的ListBox.这将实现"平滑"滚动,并隐式关闭虚拟化.要明确禁用虚拟化,您可以进行设置VirtualizingStackPanel.IsVirtualizing=False.
| 归档时间: |
|
| 查看次数: |
3862 次 |
| 最近记录: |