我在 ReactiveUI 的学习曲线上苦苦挣扎,所以这个问题可能很幼稚。请帮助我理解以下之间的区别:
ObservableAsPropertyHelper<string> _input
public string Input {get {return _input.Value;}}
Run Code Online (Sandbox Code Playgroud)
和一个普通的支持变量 RaiseAndSetIfChanged:
private string _input;
public string Input {
get {return _input;}
set {RaiseAndSetIfChanged(ref _input, value);}
}
Run Code Online (Sandbox Code Playgroud)
它们是给同一只猫剥皮的两种方法,还是两种选择有不同的用例/意图?
更新:查看底部的示例
我需要在课间发消息。发布者将无限循环,调用一些方法来获取数据,然后将该调用的结果传递给OnNext. 可以有很多订阅者,但应该只有一个 IObservable 和一个长期运行的任务。这是一个实现。
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Diagnostics;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading.Tasks;
namespace UnitTestProject1
{
[TestClass]
public class UnitTest1
{
private static string GetSomeData() => "Hi";
[TestMethod]
public async Task RunMessagingAsync()
{
var subject = new Subject<string>();
//Create a class and inject the subject as IObserver
new Publisher(subject);
//Create a class and inject the subject as IObservable
new Subscriber(subject, 1.ToString());
new Subscriber(subject, 2.ToString());
new Subscriber(subject, 3.ToString());
//Run the loop for 3 seconds
await …Run Code Online (Sandbox Code Playgroud) c# publish-subscribe reactive-programming system.reactive reactiveui
我正在尝试将 ReactiveUI 与 Avalonia 一起使用。由于 Avalonia 0.10 预览版中的初始化顺序,以下代码失败:
class ViewModel : IActivatableViewModel
{
public ViewModel(){
this.WhenActivated(disposables => {
_myProperty = observable.ToProperty(this, nameof(MyProperty)).DisposeWith(disposables).
});
}
private ObservableAsPropertyHelper<object> _myProperty = null!;
public object MyProperty => _myProperty.Value;
}
Run Code Online (Sandbox Code Playgroud)
因为WhenActivated在视图绑定到 viewModel 之后调用(因此 _myProperty 为 null)。
我认为没有简单的解决方法需要大量的修改、手动提高属性等等。
所以问题是:
如何在 Avalonia 中使用 OAPH 和 WhenActivated?
使用 ReactiveUI 时,可以在 xaml 中设置绑定...
<TextBox x:Name="SomeProperty" Text="{Binding SomeProperty}" />
Run Code Online (Sandbox Code Playgroud)
或在后面的代码中
this.Bind(ViewModel, vm.SomeProperty, v => v.SomeProperty.Text);
Run Code Online (Sandbox Code Playgroud)
似乎在某些情况下(例如绑定到 ListBox 中的子对象),使用该.xaml选项似乎是唯一的方法
例如
<ListView>
<ListView.ItemTemplate>
<DataTemplate DataType="ListViewItem">
<TextBox Text="{Binding ChildViewModelProperty}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Run Code Online (Sandbox Code Playgroud)
我用错了{Binding }还是我可以混合搭配.xaml,code behind我认为合适?!
每年左右,我都有一个移动应用程序要做,我选择 Xamarin Forms 来做。在开始一个空白项目之前,我试图了解哪些框架和模式是“趋势”的,并且我正在尝试构建一些可靠的东西。
在我的最后一个应用程序中,我的研究使我使用 Autofac 为 IoC 和 MvvmLight 进行了自定义设置,以及一堆与它们配合良好的其他自定义服务。
因为我来自网络,所以我没有逃到 Reactive Extensions 浪潮中,尤其是作为一个 Angular 开发者。所以,这一次,我的设置基于 Splat(我更喜欢 Autofac,但是……权衡,你知道)和 ReactiveUI。
我很满意。但是,在我上次申请中,还有一件事让我非常不满意:导航。网络上的大多数示例都是基本的(基本导航页面上的推送/弹出),没有库可以很好地完成它,而 ReactiveUI 的导航是......好吧,有限。
所以我不得不制作我自己的根视图和导航服务,我的意思是,我没有写它,但是Kent Boogaart 在一篇博客文章中做了(如果你有兴趣回答我的问题,我建议你看一下 impl to鉴于我的用例,更好地了解限制)。它看起来不错。一开始我很喜欢它,然后我不得不处理更复杂的场景,比如导致MasterDetailPage, 和TabbedPages的登录页面。
再一次,我花了几个小时与晦涩的 XF 或 Android 异常和复杂的导航逻辑作斗争,以便制作一个处理非常常见用例的服务。我无法在网上找到有效的示例,看起来每个人都只构建具有三个屏幕的示例应用程序,除了 NavigationPage 之外没有其他任何东西。
我迷路了。
这是我目前拥有的 API,来自 Kent Boogaart 的博客。
根视图:
public interface IView
{
IObservable<IViewModel> PagePopped { get; }
IObservable<Unit> PushPage(IViewModel pageViewModel, string contract, bool resetStack, bool animate);
IObservable<Unit> PopPage(bool animate);
IObservable<Unit> PushModal(IViewModel modalViewModel, string …Run Code Online (Sandbox Code Playgroud) 我有一个窗口,它使用 ReactiveUI 交互打开第二个窗口作为模式对话框,然后从第二个窗口中的 ListBox 返回数据。
问题是当 .ShowDialog() 完成时,ViewModel 的 SelectedItem 总是评估为 null。我已经确认绑定工作正常,并且所选项目正在对话框窗口的 ViewModel 中正确更新。只有当我返回到交互时,属性才会重置为其默认值 (null)。
我在这里整理了一个最小的问题示例:
https://github.com/replicaJunction/ReactiveDialogTest
被测的主要逻辑在 MainWindowViewModel.cs 中。
编辑:这是代码中的一个片段,其基本思想是:
GetNumberFromDialog = new Interaction<Unit, int>();
GetNumberFromDialog.RegisterHandler(interaction =>
{
var vm = new DialogWindowViewModel();
// Get a reference to the view for this VM
var view = Locator.Current.GetService<IViewFor<DialogWindowViewModel>>();
// Set its VM to our current reference
view.ViewModel = vm;
var window = view as Window;
var dialogResult = window.ShowDialog();
// At this point, vm.SelectedNumber is expected be the number the …Run Code Online (Sandbox Code Playgroud) 感谢 @GlennWatson 指出ReactiveUI.WPF除了ReactiveUI包之外,我还需要添加对 Nuget Package 的引用。
我有一个ReactiveObject视图模型,我想在其中使用 anOpenFileDialog来设置我的一个视图模型属性 ( PdfFilePath) 的值。我尝试过的一切都会导致The calling thread cannot access this object because a different thread owns it错误。
我意识到下面的代码不符合 MVVM,因为我在视图模型中使用了“显式引用/实例化视图的类型”的代码,但我只是在寻找一个可以工作的最小示例,以便我可以向后工作,将视图和视图模型代码分开,并最终将服务传递给我的视图模型,该服务处理整个“选择文件路径”部分。
public class ImportPdfViewModel : ReactiveObject
{
public ImportPdfViewModel()
{
SelectFilePathCommand = ReactiveCommand.Create(() =>
{
OpenFileDialog ofd = new OpenFileDialog() { };
//
if (ofd.ShowDialog() == DialogResult.OK)
PdfFilePath = ofd.FileName;
});
}
private string _PdfFilePath;
public string PdfFilePath
{
get => _PdfFilePath;
set => this.RaiseAndSetIfChanged(ref …Run Code Online (Sandbox Code Playgroud) 例如,我有一些集合的 observable 指示对象的状态(我通过 REST API 定期获取它)。
class User
{
int Id { get; }
string Name { get; }
string Status { get; }
}
IObservable<User> source;
Run Code Online (Sandbox Code Playgroud)
我想创建一个DynamicCache对象并在每次source给我一个新结果时更新它。所以我写道:
var models = new SourceCache<User,int>(user => user.Id);
models.Connect()
.Transform(u => new UserViewModel() {...})
...
.Bind(out viewModels)
.Subscribe();
source.Subscribe(ul => models.EditDiff(ul, (a, b) => a.Status == b.Status));
Run Code Online (Sandbox Code Playgroud)
但是现在每次用户更改其状态时,.Transform(...)方法都会创建 的新实例UserViewModel,这不是所需的行为。
当具有相同 Id 的源项更改而不是每次都创建一个新项时,我能否以某种方式确定更新现有 ViewModel 属性(在派生集合中)的规则?
我们在 .Net Core WPF 应用程序中使用 ReactiveUI.WPF 11.0.1。我们正在考虑用基于 ReactiveUI 的绑定替换所有基于 XAML 的绑定。有一个用于实现 INotifyPropertyChanged 和 INotifyDataErrorInfo 的域类型的 ViewModel:
public class ItemViewModel : INotifyPropertyChanged, INotifyDataErrorInfo
{
private string Error => string.IsNullOrEmpty(Name) ? "Empty name" : string.Empty;
private string _name;
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged();
}
}
public IEnumerable GetErrors(string propertyName)
{
if (string.IsNullOrEmpty(Error))
return Enumerable.Empty<string>();
return new[] {Error};
}
public bool HasErrors => !string.IsNullOrEmpty(Error);
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] …Run Code Online (Sandbox Code Playgroud) 我正在使用 ReactiveUI 和 Avalonia 以及 C#。
\n我在 ItemTemplate 内的 Button 上执行命令时遇到问题MyItemsControl。MyView 和 MyItemsControl 正确显示,但当我单击 ItemsTemplate 内生成的按钮时,没有任何反应,即使绑定到命令不报告任何错误。这是我的代码的模型。
看法MyView:
<UserControl\n ...\n x:Class="MyApp.MyView"\n xmlns:vm="using:MyApp.ViewModels"\n xmlns:mycontrols="clr-namespace:MyApp.MyContorls" \n DataContext="vm:MyViewModel">\n <!--Other code-->\n <mycontrols:MyItemsControl\n Name=\xe2\x80\x9cMyItemsControl1\xe2\x80\x9c>\n <!--Other code-->\n</UserControl>\nRun Code Online (Sandbox Code Playgroud)\nMyView后面的代码:
public partial class MyView : IViewFor<MyViewModel>\n{\n public MyItemsControl MyItemsControl1 => this.FindControl<MyItemsControl>("MyItemsControl1");\n\n public MyView()\n {\n this.WhenActivated(disposables =>\n {\n this.BindCommand(ViewModel, vm => vm.RemoveItemCommand, v => v.MyItemsControl1.RemoveThisItemCommand)\n .DisposeWith(disposables);\n }\n AvaloniaXamlLoader.Load(this);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n视图模型MyViewModel:
public class MyViewModel : ReactiveObject\n{\n //other …Run Code Online (Sandbox Code Playgroud) reactiveui ×10
c# ×8
wpf ×3
avaloniaui ×2
mvvm ×2
xaml ×2
architecture ×1
avalonia ×1
data-binding ×1
dynamic-data ×1
navigation ×1
properties ×1
reactive ×1
validation ×1