Create a Microsoft.CmdPal.Core.ViewModels project (#40560)

_targets #40504_ 

Major refactoring for #40113

This moves a large swath of the codebase to a `.Core` project. "Core"
doesn't have any explicit dependencies on "extensions", settings or the
current `MainListPage`. It's just a filterable list of stuff. This
should let us make this component a bit more reusable.

This is half of a PR. As I did this, I noticed a particular bit of code
for TopLevelVViewModels and CommandPaletteHost that was _very rough_.
Solving it in this PR would make "move everything to a new project" much
harder to review. So I'm submitting two PRs simultaneously, so we can
see the changes separately, then merge together.
This commit is contained in:
Mike Griese
2025-07-15 12:21:44 -05:00
committed by GitHub
parent 53bb471449
commit cc16b61eb7
121 changed files with 733 additions and 571 deletions

View File

@@ -0,0 +1,90 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using CommunityToolkit.Mvvm.ComponentModel;
using ManagedCommon;
namespace Microsoft.CmdPal.Core.ViewModels;
public abstract partial class ExtensionObjectViewModel : ObservableObject
{
public WeakReference<IPageContext> PageContext { get; set; }
public ExtensionObjectViewModel(IPageContext? context)
{
var realContext = context ?? (this is IPageContext c ? c : throw new ArgumentException("You need to pass in an IErrorContext"));
PageContext = new(realContext);
}
public ExtensionObjectViewModel(WeakReference<IPageContext> context)
{
PageContext = context;
}
public async virtual Task InitializePropertiesAsync()
{
var t = new Task(() =>
{
SafeInitializePropertiesSynchronous();
});
t.Start();
await t;
}
public void SafeInitializePropertiesSynchronous()
{
try
{
InitializeProperties();
}
catch (Exception ex)
{
ShowException(ex);
}
}
public abstract void InitializeProperties();
protected void UpdateProperty(string propertyName)
{
DoOnUiThread(() => OnPropertyChanged(propertyName));
}
protected void ShowException(Exception ex, string? extensionHint = null)
{
if (PageContext.TryGetTarget(out var pageContext))
{
pageContext.ShowException(ex, extensionHint);
}
}
protected void DoOnUiThread(Action action)
{
if (PageContext.TryGetTarget(out var pageContext))
{
Task.Factory.StartNew(
action,
CancellationToken.None,
TaskCreationOptions.None,
pageContext.Scheduler);
}
}
protected virtual void UnsafeCleanup()
{
// base doesn't do anything, but sub-classes should override this.
}
public virtual void SafeCleanup()
{
try
{
UnsafeCleanup();
}
catch (Exception ex)
{
Logger.LogDebug(ex.ToString());
}
}
}