This commit is contained in:
neuecc 2021-09-22 20:19:11 +09:00
parent 2372ab4295
commit 38ac6e817a
3 changed files with 133 additions and 33 deletions

135
README.md
View File

@ -55,30 +55,120 @@ PM> Install-Package [ObservableCollections](https://www.nuget.org/packages/Obser
create new `ObservableList<T>`, `ObservableDictionary<TKey, TValue>`, `ObservableHashSet<T>`, `ObservableQueue<T>`, `ObservableStack<T>`, `ObservableRingBuffer<T>`, `ObservableFixedSizeRingBuffer<T>`. create new `ObservableList<T>`, `ObservableDictionary<TKey, TValue>`, `ObservableHashSet<T>`, `ObservableQueue<T>`, `ObservableStack<T>`, `ObservableRingBuffer<T>`, `ObservableFixedSizeRingBuffer<T>`.
```csharp ```csharp
// Blazor simple sample. // Basic sample, use like ObservableCollection<T>.
public partial class Index : IDisposable // CollectionChanged observes all collection modification
var list = new ObservableList<int>();
list.CollectionChanged += List_CollectionChanged;
list.Add(10);
list.Add(20);
list.AddRange(new[] { 10, 20, 30 });
static void List_CollectionChanged(in NotifyCollectionChangedEventArgs<int> e)
{ {
ObservableList<int> list; switch (e.Action)
public ISynchronizedView<int, int> ItemsView { get; set; }
protected override void OnInitialized()
{ {
list = new ObservableList<int>(); case NotifyCollectionChangedAction.Add:
ItemsView = list.CreateView(x => x); if (e.IsSingleItem)
{
ItemsView.CollectionStateChanged += action => Console.WriteLine(e.NewItem);
{ }
InvokeAsync(StateHasChanged); else
}; {
} foreach (var item in e.NewItems)
{
public void Dispose() Console.WriteLine(item);
{ }
ItemsView.Dispose(); }
break;
// Remove, Replace, Move, Reset
default:
break;
} }
} }
``` ```
Handling All CollectionChanged event manually is difficult. ObservableCollections has SynchronizedView that transform element for view.
```csharp
var list = new ObservableList<int>();
var view = list.CreateView(x => x.ToString() + "$");
list.Add(10);
list.Add(20);
list.AddRange(new[] { 30, 40, 50 });
list[1] = 60;
list.RemoveAt(3);
foreach (var (_, v) in view)
{
// 10$, 60$, 30$, 50$
Console.WriteLine(v);
}
// Dispose view is unsubscribe collection changed event.
view.Dispose();
```
Blazor
---
```csharp
public partial class DataTable<T> : ComponentBase, IDisposable
{
[Parameter, EditorRequired]
public IReadOnlyList<T> Items { get; set; } = default!;
[Parameter, EditorRequired]
public Func<T, Cell[]> DataTemplate { get; set; }
ISynchronizedView<T, Cell[]> view = default!;
protected override void OnInitialized()
{
// TODO: CreateSortedView
if (Items is IObservableCollection<T> observableCollection)
{
view = observableCollection.CreateView(DataTemplate);
}
else
{
var freezedList = new FreezedList<T>(Items);
view = freezedList.CreateView(DataTemplate);
}
view.CollectionStateChanged += async _ =>
{
await InvokeAsync(StateHasChanged);
};
}
public void Dispose()
{
// unsubscribe.
view.Dispose();
}
}
// .razor, iterate view
@foreach (var (row, cells) in view)
{
<tr>
@foreach (var item in cells)
{
<td>
<CellView Item="item" />
</td>
}
</tr>
}
```
WPF
---
```csharp ```csharp
// WPF simple sample. // WPF simple sample.
@ -102,6 +192,9 @@ protected override void OnClosed(EventArgs e)
} }
``` ```
Unity
---
```csharp ```csharp
// Unity, with filter sample. // Unity, with filter sample.
@ -138,7 +231,7 @@ public class SampleScript : MonoBehaviour
this.root = root; this.root = root;
} }
public void OnCollectionChanged(ChangedKind changedKind, int value, GameObject view) public void OnCollectionChanged(ChangedKind changedKind, int value, GameObject view, in NotifyCollectionChangedEventArgs<int> eventArgs)
{ {
if (changedKind == ChangedKind.Add) if (changedKind == ChangedKind.Add)
{ {
@ -173,6 +266,7 @@ TODO: write more usage...
View/SoretedView View/SoretedView
--- ---
Filter Filter
--- ---
@ -182,9 +276,6 @@ Collections
Freezed Freezed
--- ---
Unity
---
License License
--- ---

View File

@ -3,6 +3,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>

View File

@ -1,16 +1,24 @@
using ObservableCollections; using ObservableCollections;
using System; using System;
using System.Collections.Specialized;
namespace ConsoleApp
// Basic sample, use like ObservableCollection<T>.
// CollectionChanged observes all collection modification
var list = new ObservableList<int>();
var view = list.CreateView(x => x.ToString() + "$");
list.Add(10);
list.Add(20);
list.AddRange(new[] { 30, 40, 50 });
list[1] = 60;
list.RemoveAt(3);
foreach (var (_, v) in view)
{ {
class Program // 10$, 60$, 30$, 50$
{ Console.WriteLine(v);
static void Main(string[] args)
{
var oc = new ObservableList<int>();
oc.AddRange(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.AsEnumerable());
}
}
} }
// Dispose view is unsubscribe collection changed event.
view.Dispose();