This commit is contained in:
Dan Clark
2024-11-20 21:00:09 +00:00
parent 736fd2802b
commit 8466d23aa6
8 changed files with 129 additions and 98 deletions
@@ -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)
+2 -1
View File
@@ -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,
+3
View File
@@ -4,3 +4,6 @@ public interface IActivation
{
bool IsActive { get; set; }
}
public interface IActivation<TViewModel> :
IActivation;
+27 -7
View File
@@ -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();
}
+33 -76
View File
@@ -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;
}
}
}
}
+2 -2
View File
@@ -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);