如果你有一个绑定到 CollectionView 的 ComboBox。在该 CollectionView 上发出 REFRESH 并过滤掉某些项目,从而更改所选项目的位置并将 Collection 的大小减小到 SelectedItemIndex 以下。然后它使组合框处于不可用状态。从下面的示例
- 按下设置选定项目的按钮
- 然后我在collectionview上发出刷新
- 视觉上一切看起来都很棒......因为在 Combobox 中,您看到 5 作为所选项目
- 单击组合框,SL 崩溃并出现恼人的错误
我将它追溯到 ComboBox 中的一个部分,在打开它时它会将 SelectedItemIndex 传递给方法 SetContentPresenter。但是 SelectedItemIndex 是错误的,所以它崩溃了:-(
这是我的视图模型代码
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"));
}
}
}
型号代码
public class DataObject
{
public int Id { get; set; }
public string Description { get; set; }
public override string ToString()
{
return Description;
}
}
查看代码
<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>
代码背后
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());
}
}
我最终在我的项目中解决了这个问题,没有对组合框 selecteditem 进行双向绑定,而是使用 CollectionView 上的 CurrentItem 作为我的 VM 和组合框之间的通信管道。这样,我可以在发出刷新之前使当前项目为空,然后我可以设置保持组合框处于一致状态的当前项目。
在应用程序中,此组合框是级联组合框实现的一部分。因此,在另一个组合框中选择一个项目会导致另一个组合框被过滤掉,但已经选择的项目可能仍然是一个可行的选项。