runceel / ReactiveProperty

ReactiveProperty provides MVVM and asynchronous support features under Reactive Extensions. Target frameworks are .NET 6+, .NET Framework 4.7.2 and .NET Standard 2.0.
MIT License
903 stars 101 forks source link

Feature request for ReactiveProperty.R3 #487

Open runceel opened 4 months ago

runceel commented 4 months ago

Please let us know which classes and methods are blockers when migrating from ReactiveProperty to R3.

For Japanese: It’s okay to write in Japanese.(日本語で書いても大丈夫です。)

Candidate features

Funkest commented 4 months ago

Read-only BindableReactiveProperty class

hsytkm commented 4 months ago

ObservableCollection\.ObserveElementProperty\<TElement, TPropert>() method!!

runceel commented 4 months ago

@Funkest Thank you for your feature request. At first, this feature would be beneficial if added to R3. So I created an issue for that on R3 repo.

runceel commented 4 months ago

@hsytkm I added it to list to implement for ReactiveProperty.R3!

Funkest commented 4 months ago

@runceel Tx!

runceel commented 3 months ago

@Funkest neuecc (R3 author) have added IReadOnlyBindableReactiveProperty. Could you check it?

Funkest commented 3 months ago

It checked working on xaml in WPF. For me frankly, I still hope generic one. I use (ReadOnly)ReactivePropertySlim seamless between domain and UI layers. On domain layer, If it were non-generic, I think it would be quite inconvenient to use.

However, it's sufficient to convert all R3.ReadOnlyReactiveProperty to IBindableReactiveProperty in the ViewModel. Since I don't directly make Binding the domain layer models to XAML, it's not particularly difficult.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel(new SomeDomainModel());
    }

    public class ViewModel
    {
        public IReadOnlyBindableReactiveProperty WordsCount { get; }
        public ReactiveCommand<object> AddRandomWord { get; } = new();

        public ViewModel(ISomeDomainModel someDomainModel)
        {
            WordsCount = someDomainModel.WordsCount.ToReadOnlyBindableReactiveProperty();
            AddRandomWord.Subscribe(_ => someDomainModel.AddWord($"{Random.Shared.Next()}"));
        }
    }

    public class SomeDomainModel : ISomeDomainModel
    {
        readonly List<string> words = [];
        readonly ReactiveProperty<int> wordsCount = new();

        public ReadOnlyReactiveProperty<int> WordsCount => wordsCount.ToReadOnlyReactiveProperty();

        public void AddWord(string word)
        {
            words.Add(word);
            wordsCount.Value++;
        }
    }

    public interface ISomeDomainModel
    {
        ReadOnlyReactiveProperty<int> WordsCount { get; }
        void AddWord(string word);
    }
}
Funkest commented 3 months ago

@runceel fixed a 11th line, sorry. (old shows IBindableReactiveProperty)

zerodev1200 commented 3 months ago

すばらしいプロダクトをご提供いただきありがとうございます!

ObservableCollectionsの内容になりますが、IFilteredReadOnlyObservableCollectionが欲しいです。 こちらのページのとおりISynchronizedViewFilterでフィルタリングができていましたが、ObservableCollections v2.2.0で非GenericsのIListが実装されたため(?)使用できなくなりました。

上記とは関係ない質問ですが、完了したタスクのReactiveCommand.ObserveHasErrors(BindableReactiveProperty.のタイポ?)のように、別ライブラリのクラスにプロパティを追加するのはどうやって実現しているのでしょうか。

Here is a translation from ChatGPT

Thank you for providing such an excellent product!

I would like to have an IFilteredReadOnlyObservableCollection for working with ObservableCollections. Previously, I was able to filter using ISynchronizedViewFilter as described on this page, but it seems that after the implementation of the non-generic IList in ObservableCollections v2.2.0, this functionality is no longer available.

This is an unrelated question, but how do you add properties to classes from another library, like ReactiveCommand.ObserveHasErrors for completed tasks (Is this a typo of BindableReactiveProperty?)?

neuecc commented 3 months ago

Ah, the fact that ObservableCollections can no longer be filtered in v2.2.0 is not desirable. I'll try to fix it.

zerodev1200 commented 3 months ago

@neuecc I’m not sure if this is the right place to post this, but I wanted to document what I found.

To retrieve type information of the bound list:

private void Button_Click(object sender, RoutedEventArgs e)
{
    var dg = (FindName("DG") as DataGrid);
    var itemsSource = dg.ItemsSource;
    var collectionViewType = CollectionViewSource.GetDefaultView(itemsSource).GetType();
    Debug.WriteLine($"{collectionViewType}");
}

I haven't been able to debug WPF itself beyond this point, so I’m not entirely sure what’s happening.

My guess is that the INotifyCollectionChangedSynchronizedView<TView>.Count represents the number of items before filtering, which might mean that all the lists are passed when a new ListCollectionView is created.

This is as far as I could figure out. I hope it helps.

runceel commented 3 months ago

@Funkest The generic one was released on R3 v1.2.3.

neuecc commented 2 months ago

ObservableCollections v3.0.0 reflects filtered collection.

zerodev1200 commented 2 weeks ago

I have just released a library called R3Utility. Please try using it if you like. (ObservableCollection<TElement>.ObserveElementProperty<TElement, TPropert>() method is not implemented yet)

zerodev1200 commented 1 week ago

ObservableCollections.IObservableCollection<T>.ObserveElementProperty() is now supported in R3Utility v0.2.0. Much of the code is referenced in this repository. Thank you.