我已经使用Caliburn.Micro构建了一个现有的Wpf应用程序,我希望开始集成ReactiveUI。首先,我从Caliburn.Micro切换到了Caliburn.Micro.ReactiveUI库。
我有一个ListBox,它使用卡利伯恩公司的约定绑定到一个BindableCollection。我使用CM来定位MyViewModel的视图,BindableCollection是从EntityFramework执行的搜索中填充的。
我正在尝试实现所示的异步“引人注目的示例”,但是每当执行搜索时,ReactiveUI.dll都会抛出和未处理的InvalidCastException。我无法看到任何细节,因为我没有ReactiveUI.pdb符号文件。我正在将我的BindableCollection属性包装在一个ObservableAsPropertyHelper中,以便在用户执行搜索时,ReactiveUI将更新BindableCollection,以便Caliburn.Micro可以像往常一样执行它。
有人知道什么会导致无效的强制转换异常吗?我对CM有一定的经验,但对于Rx和RxUI,我完全是新手。所以,我可能完全搞错了。
以下是相关代码:
public class MainViewModel: ReactiveScreen
{
private ObservableAsPropertyHelper<BindableCollection<MyViewModel>> _myViewModels;
public BindableCollection<MyViewModel> MyViewModels
{
get { return _myViewModels.Value; }
}
[ImportingConstructor]
public MainViewModel(IEventAggregator eventAggregator)
{
_myEntities = new myEntities();
var searchService = new SearchService(_myEntities);
Items.CollectionChanged += delegate
{
NotifyOfPropertyChange(() => Status);
};
var searchTerms = this
.ObservableForProperty(x => x.SearchTerm)
.Value()
.Throttle(TimeSpan.FromSeconds(.5));
var searchResults = searchTerms.SelectMany(searchTerm => searchService.SearchAsync(searchTerm));
var latestMatches = searchTerms
.CombineLatest(searchResults,
(searchTerm, searchResult) =>
searchResult.SearchTerm != searchTerm
? null
: searchResult.Matches)
.Where(matches => matches != null);
_myViewModels= latestMatches.ToProperty(this, x => x.MyViewModels);
}
}SearchService看起来是这样的:
public class SearchService
{
private MyEntities _myEntities;
public SearchService(MyEntities myEntities)
{
_myEntities= myEntities;
}
public async Task<SearchResult> SearchAsync(string searchTerm)
{
var query = await (from m in _myEntities.Employees select m).ToListAsync();
if (!String.IsNullOrEmpty(searchTerm))
{
searchTerm = searchTerm.Trim();
query = (List<Employee>) query.Where(
x => x.LastName.Contains(searchTerm) || x.FirstName.Contains(searchTerm))
.Select(x => x);
}
return new SearchResult
{
SearchTerm = searchTerm,
Matches = new BindableCollection<MyViewModel>(query.Select(x => new MyViewModel{ Employee = x }))
};
}
}SearchResult:
public class SearchResult
{
public string SearchTerm { get; set; }
public BindableCollection<MyViewModel> Matches { get; set; }
}谢谢,
肖恩
编辑:
在将断点设置在不同的位置之后,我得到了异常的详细信息。
消息:
{“OnError发生在将中断绑定或命令的对象(通常为ObservableAsPropertyHelper)上。为此,请订阅对象的ThrownExceptions属性”}
内部例外:
{“无法强制转换WhereSelectListIterator2[HR.DataContext.Models.Employee,HR.DataContext.Models.Employee]' to type System.Collections.Generic.List1HR.DataContext.Models.Employee'."}类型的对象”
StackTrace:
at ReactiveUI.RxApp.<>c__DisplayClass5.<.cctor>b__2()
at System.Reactive.Concurrency.Scheduler.Invoke(IScheduler scheduler, Action action)
at System.Reactive.Concurrency.DispatcherScheduler.<>c__DisplayClass1`1.<Schedule>b__0()
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)发布于 2016-01-18 00:36:07
你的问题就在眼前:
query = (List<Employee>)
query
.Where(x => x.LastName.Contains(searchTerm)
|| x.FirstName.Contains(searchTerm))
.Select(x => x);查询的类型似乎是List<Employee>,但query.Where(...).Select(...)返回的类型不是。
您需要在末尾添加一个.ToList()。它应该是这样的:
query = //(List<Employee>) no need to cast now
query
.Where(x => x.LastName.Contains(searchTerm)
|| x.FirstName.Contains(searchTerm))
.ToList();我删除了.Select(x => x),因为它什么也没做。
https://stackoverflow.com/questions/34843768
复制相似问题