我正在为Win Store,WP8,iOS,Droid上的一个主要制药项目比较MvvmCross和ReactiveUI.我们已经选择了Xamarin.
我对ReactiveUI完全不熟悉.我非常喜欢我原则上所看到的,我认为保罗是个天才.然而,细节正在成为一个真正的熊.我花了几天时间跟踪文档(手册是从2011年开始的,看起来几乎完全过时了 - 它甚至没有包含"路由器"这个词)和示例代码.
我正在查看ReactiveUI.Samples中的示例.还有来自ReactiveUI解决方案的项目MobileSample-RT.
我基于ReactiveUI.Samples"路由"示例创建了我的小小世界.坦率地说,这不是一个例子,因为它只是从AppBootstrapper导航到唯一的视图.我正在尝试做一些类似于MobileSample-RT的"三页"示例.问题是,如果我在我的项目中尝试这样的事情:
HostScreen.Router.Navigate.Execute(RxApp.DependencyResolver.GetService(typeof(LoginViewModel)));
Run Code Online (Sandbox Code Playgroud)
它崩溃了(ReactiveUI.dll中没有加载pdb符号)
如果我试试这个:
HostScreen.Router.NavigateCommandFor<LoginViewModel>().Execute(HostScreen);
Run Code Online (Sandbox Code Playgroud)
同样的结果 - 硬碰撞.这真的让我觉得它似乎应该"正常工作".
我可以这样称呼:
HostScreen.Router.Navigate.Execute(new LoginViewModel(HostScreen));
Run Code Online (Sandbox Code Playgroud)
正如预期的那样,它确实在我看来.我还在主屏幕上连接了一个后退按钮:
this.OneWayBind(AppBootstrapper, x => x.Router.NavigateBack, x => x.BackButton.Command);
Run Code Online (Sandbox Code Playgroud)
这确实从我刚刚浏览过的视图中回过来.
所以现在我想再次向前迈进.我点击执行此操作的按钮(再次):
HostScreen.Router.Navigate.Execute(new LoginViewModel(HostScreen));
Run Code Online (Sandbox Code Playgroud)
我回到那个观点.但是这次需要在后退按钮上单击2次才能实际返回.如果我再向前移动,则下次需要3次点击.NavigationStack正在填充LoginViewModel的新实例.
那么,路由/导航的正确方法是什么?为什么这些命令会崩溃?而不是每次在Navigate.Execute中调用"new",我如何导航到已经在导航堆栈中的视图模型(或者它应该首先在那里?).
非常感谢您提供的任何清晰度.
我正在使用Visual Studio 13社区.创建了一个简单的WinForms项目,创建了一个空类并继承了ReactiveObject.我已经使用NuGet安装了reactivui-winforms 6.5.0.我可以看到ver 1.0.0已安装并且Splat在引用中.
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ReactiveUI;
using Splat;
namespace ReactiveSplatTest
{
class ReactiveObjectTest : ReactiveObject
{
}
}
Run Code Online (Sandbox Code Playgroud)
在Splat引用的属性中,路径是:
c:\users\rick reynolds\documents\visual studio
2013\Projects\ReactiveSplatTest\packages\Splat.1.0.0\lib\Net45\Splat.dll
Run Code Online (Sandbox Code Playgroud)
我已经证实这是正确的道路.那个文件Splat.dll确实存在.
C:\Users\Rick Reynolds\Documents\Visual Studio
2013\Projects\ReactiveSplatTest\packages\Splat.1.0.0\lib\Net45
Run Code Online (Sandbox Code Playgroud)
我每次建立时都会收到此警告和错误...
警告1:
Reference to type 'Splat.IEnableLogger' claims it is defined in 'c:\Users\Rick Reynolds\Documents\Visual Studio
2013\Projects\ReactiveSplatTest\packages\Splat.1.0.0\lib\Net45\Splat.dll',
but it could not be found c:\Users\Rick Reynolds\Documents\Visual Studio
2013\Projects\ReactiveSplatTest\packages\reactiveui-
core.6.5.0\lib\Net45\ReactiveUI.dll ReactiveSplatTest
Run Code Online (Sandbox Code Playgroud)
错误2:
The base class or interface 'Splat.IEnableLogger' in assembly 'Splat,
Version=1.6.2.0, Culture=neutral, PublicKeyToken=null' …Run Code Online (Sandbox Code Playgroud) 我正在切换到最新版本的ReactiveUI(7.0),我遇到了一些不兼容问题,并想知道建议的方法来处理这个问题:
ReactiveUI 6.x
Texts.Events().MouseUp
.InvokeCommand(ViewModel, x => x.DoSomething);
Run Code Online (Sandbox Code Playgroud)
现在抛出异常:
Command需要System.Reactive.Unit类型的参数,但接收的类型为System.Windows.Input.MouseButtonEventArgs的参数.
我通过使用以下代码修复此问题,但这是正确的方法吗?
Texts.Events().MouseUp
.Select(x => Unit.Default)
.InvokeCommand(ViewModel, x => x.DoSomething);
Run Code Online (Sandbox Code Playgroud) 目前我有以下Rx/ReactiveUI代码块:
this.WhenAnyValue(x => x.Listras)
.Where(item => item != null)
.Throttle(TimeSpan.FromMilliseconds(millis))
.ObserveOn(TaskPoolScheduler.Default)
.Select(im => GetArray.FromChannels(im, 0, 1))
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.Grayscale, out _grayscale);
this.WhenAnyValue(x => x.Grayscale)
.Where(item => item != null)
.Throttle(TimeSpan.FromMilliseconds(millis))
.ObserveOn(TaskPoolScheduler.Default)
.Select(ar => Gaussian.GaussianConvolution(ar, 1.5))
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.BlurMenor, out _blurMenor);
this.WhenAnyValue(x => x.BlurMenor)
.Where(item => item != null)
.Throttle(TimeSpan.FromMilliseconds(millis))
.ObserveOn(TaskPoolScheduler.Default)
.Select(ar => { ConversorImagem.Converter(ar, out BitmapSource im); return im; })
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.ImagemBlurMenor, out _imagemBlurMenor);
this.WhenAnyValue(x => x.BlurMenor)
.Where(item => item != null)
.Throttle(TimeSpan.FromMilliseconds(millis)) …Run Code Online (Sandbox Code Playgroud) 我有一个类似ReactiveUI的视图模型.它有几个不同类型的属性来触发NotifyPropertyChanged事件,我想订阅一个方法,当任何被触发时将被调用,但我对实际值不感兴趣.
我当前的代码有点难看(由于true选择不透明).有没有办法表达这一点,这表明在事件发生时只关心他人的意图?
this.ObservableForProperty(m => m.PropertyOne)
.Select(_ => true)
.Merge(this.ObservableForProperty(m => m.PropertyTwo).Select(_ => true))
.Subscribe(...)
Run Code Online (Sandbox Code Playgroud)
我正在合并8个属性,所以它比显示的更难看.
我从博客中查看了ReactiveUi的示例,我想知道ReactiveUI是否在下面有某种订阅管理工具,或者是忽略了它们可能泄漏订阅这一事实的例子?
每当我在ReactiveUi中调用一个导致a的方法时IDisposable,我是否需要保留该引用并自己跟踪它?这也意味着我的ViewModel需要是一次性的,这似乎很难,因为我们不知道什么时候连接的"视图"消失了(即如果我的ViewModel反映了数据网格中的项目),所以似乎没有合适的叫做处置的地方.
我试图第一次使用WhenAnyObservable.
当ReactiveList Count == 0且tipText长度> 0时,我想在订阅中将本地值设置为true,或者相反.
this.ViewModel.WhenAnyObservable(
x => x.AutoCompleteItems.CountChanged,
x => x.ObservableForProperty(y => y.TipText),
(countChanged, tipText) => countChanged == 0 && tipText.Length > 0);
Run Code Online (Sandbox Code Playgroud)
我无法让这个工作.
有什么技巧我应该做,或者我应该使用其他WhenAny命令之一?
我想知道绑定到ReactiveCommand的推荐方法IsExecuting.
问题是初始命令执行(在构造函数结束时启动)不是使用IsLoading绑定更新WPF控件,尽管后续调用按预期工作.
更新2添加测试绑定代码
这显示了装饰器内容时IsLoading为真
<ac:AdornedControl IsAdornerVisible="{Binding IsLoading}">
<ac:AdornedControl.AdornerContent>
<controls1:LoadingAdornerContent/>
</ac:AdornedControl.AdornerContent>
<fluent:ComboBox
ItemsSource="{Binding Content, Mode=OneWay}"
DisplayMemberPath="Name"
SelectedValuePath="ContentId"
SelectedValue="{Binding SelectedContentId}"
IsSynchronizedWithCurrentItem="True"
/>
</ac:AdornedControl>
Run Code Online (Sandbox Code Playgroud)
更新
我发现了这个:https: //github.com/reactiveui/rxui-design-guidelines
并认为我应该能够做到这样的事情:
this._isLoading = this.WhenAnyValue(x => x.LoadCommand.IsExecuting)
.ToProperty(this, x => x.IsLoading);
Run Code Online (Sandbox Code Playgroud)
但它给出了编译错误:
方法'ReactiveUI.OAPHCreationHelperMixin.ToProperty <TObj,TRet>的类型参数(System.IObservable <TRet>,TObj,System.Linq.Expressions.Expression <System.Func <TObj,TRet >>,TRet,System.Reactive. Concurrency.IScheduler)'无法从用法中推断出来.尝试显式指定类型参数.
我也尝试过:
this._isLoading = this.WhenAnyValue(x => x.LoadCommand.IsExecuting)
.ToProperty<TheViewModel, bool>(this, x => x.IsLoading);
Run Code Online (Sandbox Code Playgroud)
但得到编译错误:
'System.IObservable <System.IObservable <bool >>'不包含'ToProperty'的定义和最佳扩展方法重载'ReactiveUI.OAPHCreationHelperMixin.ToProperty <TObj,TRet>(System.IObservable <TRet>,TObj,System .Linq.Expressions.Expression <System.Func <TObj,TRet >>,TRet,System.Reactive.Concurrency.IScheduler)'有一些无效的参数
和
实例参数:无法从'System.IObservable>'转换为'System.IObservable'
原来下面
我的帖子末尾列出的代码通过访问IsLoading属性来进行初始绑定,听起来就像启动订阅一样.但是从进一步的阅读来看,我似乎应该使用它WhenAny,我似乎无法弄清楚我的鼻子前面放了什么: …
我正在尝试将我的项目从ReactiveUI 6.5转换为版本7.在旧版本中我调用了
// var command = ReactiveCommand.Create...;
// ...
if(command.CanExecute(null))
command.Execute(null);
Run Code Online (Sandbox Code Playgroud)
为了从我的代码后面执行命令.
现在,CanExecute方法不再可用,并替换为属性IObservable<bool>.如果我只是打电话Execute().Subscribe()或者我必须明确地调用它,是否会自动调用CanExecute Observable ?
现在我用上面的代码替换了
command.Execute().Subscribe();
Run Code Online (Sandbox Code Playgroud) 我将UserControl更改为ReactiveUserControl,现在我无法查看设计视图.有什么办法可以让设计师使用ReactiveUserControl吗?