В приведенном ниже фрагменте, похоже, что transform(x => x.Bar.Baz)
только пересылает изменения, если элементы в sl2
добавляются или удаляются, но не при изменении значения Baz
. Это ожидаемое поведение? Как это изменить, чтобы все модификации были найдены в transformed
?
SourceList<FooClass> sl2 = new SourceList<FooClass>();
sl2.Connect()
.Transform(x => x.Bar.Baz)
.Bind(out ReadOnlyObservableCollection<String> transformed)
.Subscribe( x=> { Console.WriteLine("CHANGE from Subscribe"); } );
Полный код читается как. Пример выполнения также доступен на GitHub
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace ReactivUI_Test
{
class BarClass : ReactiveObject
{
[Reactive] public String Baz { get; set; } = "";
public BarClass(String b) { Baz = b; }
public BarClass() { Baz = "!!!"; }
public override String ToString() { return Baz.ToString(); }
}
class FooClass : ReactiveObject
{
[Reactive] public BarClass Bar { get; set; } = new BarClass();
public override String ToString() { return Bar.ToString(); }
}
class ViewModel: ReactiveObject
{
[Reactive] FooClass Foo { get; set; } = new FooClass();
void PrintList<T> (IEnumerable<T> items)
{
foreach (T item in items)
{
Console.WriteLine(item.ToString());
}
}
public ViewModel()
{
Console.WriteLine("=== ===");
SourceList<FooClass> sl2 = new SourceList<FooClass>();
FooClass fo1 = new FooClass() { Bar = new BarClass("Hello ") };
FooClass fo2 = new FooClass() { Bar = new BarClass("World ") };
FooClass fo3 = new FooClass() { Bar = new BarClass("Out ") };
FooClass fo4 = new FooClass() { Bar = new BarClass("There ") };
FooClass fo5 = new FooClass() { Bar = new BarClass("!!!!!!") };
sl2.Add(fo1);
sl2.Add(fo2);
sl2.Add(fo3);
sl2.Add(fo4);
sl2.Connect()
.Transform(x => x.Bar.Baz)
.Bind(out ReadOnlyObservableCollection<String> transformed)
.Subscribe( x=> { Console.WriteLine("CHANGE from Subscribe"); } );
Console.WriteLine("=== Start ===");
((INotifyCollectionChanged)transformed).CollectionChanged +=
new NotifyCollectionChangedEventHandler(( s,e) => Console.WriteLine("CHANGE from Event Handler"));
Console.WriteLine("sl2: ");
PrintList<FooClass>(sl2.Items);
Console.WriteLine("transformed: ");
PrintList<String>(transformed);
Console.WriteLine("=== Send to Space ===");
fo2.Bar.Baz = "Space";
Console.WriteLine("sl2: ");
PrintList<FooClass>(sl2.Items);
Console.WriteLine("transformed: ");
PrintList<String>(transformed);
Console.WriteLine("=== Add !!!! ===" );
sl2.Add(fo5);
Console.WriteLine("sl2: ");
PrintList<FooClass>(sl2.Items);
Console.WriteLine("transformed: ");
PrintList<String>(transformed);
Console.WriteLine("=== ===");
Console.WriteLine("Finish");
Console.ReadLine();
}
}
class Program
{
static void Main(string[] args)
{
ViewModel vm = new ViewModel();
}
}
}
Вывод не тот, на который я рассчитывал. Кажется, что .Transform(x => x.Bar.Baz)
только перенаправляет обновления, элементы добавляются или удаляются из списка 'sl2'. Если есть изменения значения Bar.Baz
, эти изменения не будут переданы в transformed
.
Мой вывод:
=== ===
CHANGE from Subscribe
=== Start ===
sl2:
Hello
World
Out
There
transformed:
Hello
World
Out
There
=== Send to Space ===
sl2:
Hello
Space
Out
There
transformed:
Hello
World <--- I would have hoped to have 'Space' here
Out
There
=== Add !!!! ===
CHANGE from Event Handler <-- I would have hoped that event handlers are triggered at World->Space
CHANGE from Subscribe <-- I would have hoped that event handlers are triggered at World->Space
sl2:
Hello
Space
Out
There
!!!!!!
transformed:
Hello
World <--- I would have hoped to have 'Space' here
Out
There
!!!!!!
=== ===
Finish
Обратите внимание: (1) в transformed
Смена Мира-> Пространство никогда не делается. В sl2
это изменение сделано.
(2) CollectionChangedEvent запускается только после добавления в Item добавлено.
Мой вопрос:
Как убедиться, что transform()
устанавливает правильные уведомления?
Обновление
В зависимости от ответа Funk ниже, это должно быть исправлено с помощью:
sl2.Connect()
.AutoRefresh(x => x.Bar.Baz)
.Transform(x => x.Bar.Baz)
...
Однако это не меняет вывод.