C# 在SL组合框上使用CollectionView刷新时,SelectedItemIndex不匹配
如果将组合框绑定到CollectionView。对该CollectionView发出刷新,并过滤掉某些项目,从而更改所选项目的位置,并将集合的大小减小到SelectedItemIndex以下。然后它使组合框处于不可用状态。从下面的示例中C# 在SL组合框上使用CollectionView刷新时,SelectedItemIndex不匹配,c#,.net,silverlight,combobox,silverlight-5.0,C#,.net,Silverlight,Combobox,Silverlight 5.0,如果将组合框绑定到CollectionView。对该CollectionView发出刷新,并过滤掉某些项目,从而更改所选项目的位置,并将集合的大小减小到SelectedItemIndex以下。然后它使组合框处于不可用状态。从下面的示例中 按下按钮可设置selecteditem 然后我对collectionview进行刷新 看起来一切都很好。。。因为在组合框中,您将5视为所选项目 单击组合框,SL崩溃并出现恼人的错误 我将它追溯到组合框中的一个部分,在打开它时,它将SelectEditedIn
- 按下按钮可设置selecteditem
- 然后我对collectionview进行刷新
- 看起来一切都很好。。。因为在组合框中,您将5视为所选项目
- 单击组合框,SL崩溃并出现恼人的错误
public class MainPageViewModel : INotifyPropertyChanged
{
public ObservableCollection<DataObject> ItemSource;
public ICollectionView CollectionView { get; set; }
public MainPageViewModel()
{
ItemSource = new ObservableCollection<DataObject>();
var source = new CollectionViewSource();
for (int i = 0; i < 10; i++ )
{
ItemSource.Add(new DataObject(){ Id = i, Description = i.ToString()});
}
Filters = new List<string>();
source.Source = ItemSource;
CollectionView = source.View;
CollectionView.Filter = (x) =>
{
if (Filters.Count == 0)
return true;
return Filters.Contains((x as DataObject).Description);
};
}
public event PropertyChangedEventHandler PropertyChanged;
internal void ButtonPushed()
{
SelectedObject = ItemSource.First(x => x.Description == "5");
Filters.Add("1");
Filters.Add("5");
CollectionView.Refresh();
}
public List<string> Filters
{
get;
set;
}
DataObject _SelectedObject;
public DataObject SelectedObject
{
get
{
return _SelectedObject;
}
set
{
if (_SelectedObject != value)
{
_SelectedObject = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("SelectedObject"));
}
}
}
视图代码
<StackPanel x:Name="LayoutRoot" Background="White">
<ComboBox ItemsSource="{Binding CollectionView}" SelectedItem="{Binding SelectedObject, Mode=TwoWay}"></ComboBox>
<Button Content="Run Test" Click="Button_Click_1"></Button>
</StackPanel>
我在项目中解决了这个问题,没有对组合框selecteditem进行双向绑定,而是使用CollectionView上的CurrentItem作为VM和组合框之间的通信管道。这样,我可以在发出刷新之前将当前项设为空,然后设置保留组合框的当前项处于一致的状态
在应用程序中,此组合框是级联组合框实现的一部分。因此,在另一个组合框中选择一个项目会导致另一个组合框过滤,但已选择的项目可能仍然是可行的选项。问题似乎是您已将绑定的SelectedItem设置为特定数据对象,然后删除了该对象我不知道ComboBox除了抛出一个错误之外还能做什么,因为它的状态已经无效。所以我认为这不是ComboBox的问题 刷新后,我要做的是查看SelectedObject是否仍然是有效对象。如果不是,则将其从列表中删除。这样您就不会得到错误
internal void ButtonPushed() {
SelectedObject = ItemSource.First(x => x.Description == "5");
Filters.Add("1");
Filters.Add("5");
CollectionView.Refresh();
ValidateSelectedDataObject();
}
public void ValidateSelectedDataObject() {
DataObject currentSelectedItem = this.SelectedObject;
this.SelectedObject = null;
foreach (DataObject item in CollectionView) {
if (item.Id == currentSelectedItem.Id) {
this.SelectedObject = currentSelectedItem;
}
}
}
GregKudos,看起来您在Combobox控件中发现了一个bug。甚至可能在选择器基类中也发现了。我想知道它是否也会影响ListBox和其他派生类。-有问题吗,或者这只是一个观察结果?很酷,我在connect上记录了一个bug。因为它是SL,所以我认为这一点都不重要:-)。我想我只是在检查我没有做一些基本上愚蠢的事情,我认为这应该是可行的,而不是崩溃SL。我找不到有这个问题的其他人,所以我觉得我缺少了一些简单的东西。
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this.Loaded += MainPage_Loaded;
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = new MainPageViewModel();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var vm = DataContext as MainPageViewModel;
Dispatcher.BeginInvoke(() =>vm.ButtonPushed());
}
}
internal void ButtonPushed() {
SelectedObject = ItemSource.First(x => x.Description == "5");
Filters.Add("1");
Filters.Add("5");
CollectionView.Refresh();
ValidateSelectedDataObject();
}
public void ValidateSelectedDataObject() {
DataObject currentSelectedItem = this.SelectedObject;
this.SelectedObject = null;
foreach (DataObject item in CollectionView) {
if (item.Id == currentSelectedItem.Id) {
this.SelectedObject = currentSelectedItem;
}
}
}