WIP
This commit is contained in:
@@ -23,20 +23,14 @@ public partial class ConfigurationValueViewModel<TConfiguration, TValue>(IServic
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnActivated()
|
||||
{
|
||||
Value = read(configuration);
|
||||
base.OnActivated();
|
||||
}
|
||||
protected override void Activated() => Value = read(configuration);
|
||||
|
||||
protected override void OnChanged(TValue? value)
|
||||
protected override void Changed(TValue? value)
|
||||
{
|
||||
if (IsActive)
|
||||
{
|
||||
writer.Write(args => write(value, args));
|
||||
}
|
||||
|
||||
base.OnChanged(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,10 +91,9 @@ public partial class ConfigurationValueViewModel<TConfiguration, TValue, TItem>
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnActivated()
|
||||
protected override void Activated()
|
||||
{
|
||||
Value = read(configuration);
|
||||
base.OnActivated();
|
||||
}
|
||||
|
||||
protected override void OnChanged(TValue? value)
|
||||
|
||||
@@ -13,7 +13,8 @@ public class DefaultHostBuilder :
|
||||
.ConfigureServices((context, services) =>
|
||||
{
|
||||
services.AddScoped<IServiceFactory>(provider =>
|
||||
new ServiceFactory((type, parameters) => ActivatorUtilities.CreateInstance(provider, type,
|
||||
new ServiceFactory((type, parameters) =>
|
||||
ActivatorUtilities.CreateInstance(provider, type,
|
||||
parameters?.Where(x => x is not null).ToArray()!)));
|
||||
|
||||
services.AddSingleton<IComponentHostCollection,
|
||||
|
||||
@@ -4,3 +4,6 @@ public interface IActivation
|
||||
{
|
||||
bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
public interface IActivation<TViewModel> :
|
||||
IActivation;
|
||||
@@ -9,7 +9,7 @@ public partial class Observable(IServiceProvider provider,
|
||||
IDisposer disposer) :
|
||||
ObservableRecipient,
|
||||
IObservableViewModel,
|
||||
IActivityIndicator,
|
||||
IActivation,
|
||||
IDisposable,
|
||||
IServiceProviderRequired,
|
||||
IServiceFactoryRequired,
|
||||
@@ -22,10 +22,10 @@ public partial class Observable(IServiceProvider provider,
|
||||
|
||||
public IServiceFactory Factory { get; } = factory;
|
||||
|
||||
public IServiceProvider Provider { get; } = provider;
|
||||
|
||||
public new IMessenger Messenger { get; } = messenger;
|
||||
|
||||
public IServiceProvider Provider { get; } = provider;
|
||||
|
||||
public void Commit()
|
||||
{
|
||||
foreach (object trackedProperty in trackedProperties.Values)
|
||||
@@ -56,6 +56,26 @@ public partial class Observable(IServiceProvider provider,
|
||||
trackedProperties[propertyName] = new TrackedProperty<T>(initialValue, setter, getter);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Activated()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void Deactivated()
|
||||
{
|
||||
}
|
||||
|
||||
protected override sealed void OnActivated()
|
||||
{
|
||||
base.OnActivated();
|
||||
Activated();
|
||||
}
|
||||
|
||||
protected override sealed void OnDeactivated()
|
||||
{
|
||||
base.OnDeactivated();
|
||||
Deactivated();
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Observable<TValue> :
|
||||
@@ -73,11 +93,11 @@ public partial class Observable<TValue> :
|
||||
Value = value;
|
||||
}
|
||||
|
||||
protected virtual void OnChanged(TValue? value)
|
||||
protected virtual void Changed(TValue? value)
|
||||
{
|
||||
}
|
||||
|
||||
partial void OnValueChanged(TValue? value) => OnChanged(value);
|
||||
partial void OnValueChanged(TValue? value) => Changed(value);
|
||||
}
|
||||
|
||||
public partial class Observable<TKey, TValue> :
|
||||
@@ -100,9 +120,9 @@ public partial class Observable<TKey, TValue> :
|
||||
Value = value;
|
||||
}
|
||||
|
||||
protected virtual void OnValueChanged()
|
||||
protected virtual void ValueChanged()
|
||||
{
|
||||
}
|
||||
|
||||
partial void OnValueChanged(TValue? value) => OnValueChanged();
|
||||
partial void OnValueChanged(TValue? value) => ValueChanged();
|
||||
}
|
||||
@@ -1,13 +1,15 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reactive.Disposables;
|
||||
|
||||
namespace Toolkit.Foundation;
|
||||
|
||||
public partial class ObservableCollection<TViewModel> :
|
||||
public abstract partial class ObservableCollection<TViewModel> :
|
||||
ObservableRecipient,
|
||||
IObservableCollectionViewModel<TViewModel>,
|
||||
IList<TViewModel>,
|
||||
@@ -36,16 +38,11 @@ public partial class ObservableCollection<TViewModel> :
|
||||
|
||||
private readonly Dictionary<string, object> trackedProperties = [];
|
||||
|
||||
private bool cleaning;
|
||||
|
||||
[ObservableProperty]
|
||||
private int count;
|
||||
|
||||
private Func<TViewModel>? defaultSelectionFactory;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool initialized;
|
||||
|
||||
private bool isClearing;
|
||||
|
||||
[ObservableProperty]
|
||||
private TViewModel? selectedItem;
|
||||
|
||||
@@ -128,13 +125,7 @@ public partial class ObservableCollection<TViewModel> :
|
||||
public TViewModel Add<T>(params object?[] parameters)
|
||||
where T : TViewModel
|
||||
{
|
||||
T? item = Factory.Create<T>(args =>
|
||||
{
|
||||
if (args is IInitialization initialization)
|
||||
{
|
||||
initialization.Initialize();
|
||||
}
|
||||
}, parameters);
|
||||
T? item = Factory.Create<T>(parameters);
|
||||
|
||||
Add(item);
|
||||
return item;
|
||||
@@ -174,11 +165,6 @@ public partial class ObservableCollection<TViewModel> :
|
||||
{
|
||||
foreach (TViewModel? item in items)
|
||||
{
|
||||
if (item is IInitialization initialization)
|
||||
{
|
||||
initialization.Initialize();
|
||||
}
|
||||
|
||||
Add(item);
|
||||
}
|
||||
|
||||
@@ -187,7 +173,7 @@ public partial class ObservableCollection<TViewModel> :
|
||||
|
||||
public void Clear(bool disposeItems = false)
|
||||
{
|
||||
isClearing = true;
|
||||
cleaning = true;
|
||||
if (disposeItems)
|
||||
{
|
||||
foreach (TViewModel item in this.ToList())
|
||||
@@ -198,12 +184,12 @@ public partial class ObservableCollection<TViewModel> :
|
||||
}
|
||||
|
||||
ClearItems();
|
||||
isClearing = false;
|
||||
cleaning = false;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
isClearing = true;
|
||||
cleaning = true;
|
||||
foreach (TViewModel item in this.ToList())
|
||||
{
|
||||
Disposer.Dispose(item);
|
||||
@@ -211,7 +197,7 @@ public partial class ObservableCollection<TViewModel> :
|
||||
}
|
||||
|
||||
ClearItems();
|
||||
isClearing = false;
|
||||
cleaning = false;
|
||||
}
|
||||
|
||||
public void Commit()
|
||||
@@ -258,13 +244,7 @@ public partial class ObservableCollection<TViewModel> :
|
||||
where T :
|
||||
TViewModel
|
||||
{
|
||||
T? item = Factory.Create<T>(args =>
|
||||
{
|
||||
if (args is IInitialization initialization)
|
||||
{
|
||||
initialization.Initialize();
|
||||
}
|
||||
}, parameters);
|
||||
T? item = Factory.Create<T>(parameters);
|
||||
|
||||
InsertItem(index, item);
|
||||
UpdateSelection(item);
|
||||
@@ -337,10 +317,6 @@ public partial class ObservableCollection<TViewModel> :
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void OnInitialize()
|
||||
{
|
||||
}
|
||||
|
||||
public void Receive(RemoveEventArgs<TViewModel> args)
|
||||
{
|
||||
foreach (TViewModel item in this.ToList())
|
||||
@@ -447,13 +423,7 @@ public partial class ObservableCollection<TViewModel> :
|
||||
index = Count;
|
||||
}
|
||||
|
||||
T? item = Factory.Create<T>(args =>
|
||||
{
|
||||
if (args is IInitialization initialization)
|
||||
{
|
||||
initialization.Initialize();
|
||||
}
|
||||
}, parameters);
|
||||
T? item = Factory.Create<T>(parameters);
|
||||
|
||||
Insert(index, item);
|
||||
return true;
|
||||
@@ -475,14 +445,6 @@ public partial class ObservableCollection<TViewModel> :
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset(Action<ObservableCollection<TViewModel>> factory, bool disposeItems = true)
|
||||
{
|
||||
SelectedItem = default;
|
||||
|
||||
Clear(disposeItems);
|
||||
factory.Invoke(this);
|
||||
}
|
||||
|
||||
public void Revert()
|
||||
{
|
||||
foreach (object trackedProperty in trackedProperties.Values)
|
||||
@@ -491,26 +453,6 @@ public partial class ObservableCollection<TViewModel> :
|
||||
}
|
||||
}
|
||||
|
||||
public void SetSource(IList<TViewModel> source, Func<TViewModel>? defaultSelectionFactory)
|
||||
{
|
||||
foreach (TViewModel item in source)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
|
||||
if (defaultSelectionFactory is not null)
|
||||
{
|
||||
this.defaultSelectionFactory = defaultSelectionFactory;
|
||||
SelectedItem = defaultSelectionFactory.Invoke();
|
||||
}
|
||||
|
||||
if (source is INotifyCollectionChanged observableSource)
|
||||
{
|
||||
observableSource.CollectionChanged -= SourceCollectionChanged;
|
||||
observableSource.CollectionChanged += SourceCollectionChanged;
|
||||
}
|
||||
}
|
||||
|
||||
public void Track<T>(string propertyName, Func<T> getter, Action<T> setter)
|
||||
{
|
||||
if (!trackedProperties.ContainsKey(propertyName))
|
||||
@@ -529,7 +471,7 @@ public partial class ObservableCollection<TViewModel> :
|
||||
Disposer.Add(this, item);
|
||||
Disposer.Add(item, Disposable.Create(() =>
|
||||
{
|
||||
if (item is IDisposable && !isClearing)
|
||||
if (item is IDisposable && !cleaning)
|
||||
{
|
||||
if (item is IList collection)
|
||||
{
|
||||
@@ -543,6 +485,26 @@ public partial class ObservableCollection<TViewModel> :
|
||||
collection.Insert(index > Count ? Count : index, item);
|
||||
}
|
||||
|
||||
protected override sealed void OnActivated()
|
||||
{
|
||||
base.OnActivated();
|
||||
Activated();
|
||||
}
|
||||
|
||||
protected override sealed void OnDeactivated()
|
||||
{
|
||||
base.OnDeactivated();
|
||||
Deactivated();
|
||||
}
|
||||
|
||||
protected virtual void Activated()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void Deactivated()
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual void RemoveItem(int index) =>
|
||||
collection.RemoveAt(index);
|
||||
|
||||
@@ -610,11 +572,6 @@ public partial class ObservableCollection<TViewModel> :
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
|
||||
if (defaultSelectionFactory is not null)
|
||||
{
|
||||
SelectedItem = defaultSelectionFactory.Invoke();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Toolkit.Foundation;
|
||||
|
||||
namespace Toolkit.UI.WinUI;
|
||||
|
||||
[Bindable]
|
||||
public static class ContentTemplateBinding
|
||||
{
|
||||
public static readonly DependencyProperty IsAttachedProperty =
|
||||
DependencyProperty.RegisterAttached("IsAttached",
|
||||
typeof(bool), typeof(ContentTemplateBinding),
|
||||
new PropertyMetadata(false, OnAttachLoadedEventChanged));
|
||||
|
||||
public static bool GetIsAttached(DependencyObject dependencyObject) =>
|
||||
(bool)dependencyObject.GetValue(IsAttachedProperty);
|
||||
|
||||
public static void SetIsAttached(DependencyObject
|
||||
dependencyObject, bool value) => dependencyObject.SetValue(IsAttachedProperty, value);
|
||||
|
||||
private static void OnAttachLoadedEventChanged(DependencyObject dependencyObject,
|
||||
DependencyPropertyChangedEventArgs args)
|
||||
{
|
||||
if (dependencyObject is FrameworkElement content)
|
||||
{
|
||||
void HandleLoaded(object sender, RoutedEventArgs args)
|
||||
{
|
||||
if (content.DataContext is IActivation activation)
|
||||
{
|
||||
content.Loaded -= HandleLoaded;
|
||||
activation.IsActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleUnloaded(object sender, RoutedEventArgs args)
|
||||
{
|
||||
if (content.DataContext is IActivation activation)
|
||||
{
|
||||
content.Unloaded -= HandleUnloaded;
|
||||
activation.IsActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((bool)args.NewValue)
|
||||
{
|
||||
content.Loaded += HandleLoaded;
|
||||
content.Unloaded += HandleUnloaded;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
content.Loaded -= HandleLoaded;
|
||||
content.Unloaded -= HandleUnloaded;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,8 +38,8 @@ public class ContentTemplate :
|
||||
{
|
||||
string xamlString = @$"
|
||||
<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
|
||||
xmlns:ui=""using:{descriptor.TemplateType.Namespace}"">
|
||||
<ui:{descriptor.TemplateType.Name} />
|
||||
xmlns:Template=""using:{descriptor.TemplateType.Namespace}"">
|
||||
<Template:{descriptor.TemplateType.Name}/>
|
||||
</DataTemplate>";
|
||||
|
||||
return (DataTemplate)XamlReader.Load(xamlString);
|
||||
|
||||
Reference in New Issue
Block a user