首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ReactiveUI“引人注目的示例”搜索与Caliburn.Micro.ReactiveUI

ReactiveUI“引人注目的示例”搜索与Caliburn.Micro.ReactiveUI
EN

Stack Overflow用户
提问于 2016-01-17 21:14:34
回答 1查看 363关注 0票数 1

我已经使用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,我完全是新手。所以,我可能完全搞错了。

以下是相关代码:

代码语言:javascript
复制
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看起来是这样的:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-18 00:36:07

你的问题就在眼前:

代码语言:javascript
复制
query = (List<Employee>)
    query
        .Where(x => x.LastName.Contains(searchTerm)
            || x.FirstName.Contains(searchTerm))
        .Select(x => x);

查询的类型似乎是List<Employee>,但query.Where(...).Select(...)返回的类型不是。

您需要在末尾添加一个.ToList()。它应该是这样的:

代码语言:javascript
复制
query = //(List<Employee>) no need to cast now
    query
        .Where(x => x.LastName.Contains(searchTerm)
            || x.FirstName.Contains(searchTerm))
        .ToList();

我删除了.Select(x => x),因为它什么也没做。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34843768

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档