我有一个使用Caliburn.Micro构建的现有Wpf应用程序,我想开始集成ReactiveUI。首先,我从Caliburn.Micro切换到Caliburn.Micro.ReactiveUI库。
我有一个ListBox,它使用Caliburn Micro的约定绑定到BindableCollection。我使用CM来查找MyViewModel的视图,并使用EntityFramework执行搜索来填充BindableCollection。
我试图实现异步"引人注目的例子"显示但是每当执行搜索时,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 }))
};
}
}
信息搜索结果:
public class SearchResult
{
public string SearchTerm { get; set; }
public BindableCollection<MyViewModel> Matches { get; set; }
}
谢谢,
肖恩
编辑:
我在不同位置设置断点后得到了异常的详细信息。
消息:
{&#34;在一个会破坏绑定或命令的对象(通常是ObservableAsPropertyHelper)上发生OnError。要防止这种情况,请订阅对象的ThrownExceptions属性&#34;}
内部例外:
{&#34;无法转换类型为WhereSelectListIterator 2[HR.DataContext.Models.Employee,HR.DataContext.Models.Employee]'
to type System.Collections.Generic.List
的对象1 [HR.DataContext.Models.Employee]&#39;。&#34;}
堆栈跟踪:
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)
答案 0 :(得分:1)
你的问题在线:
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)
,因为它没有做任何事情。