mirror of
https://github.com/2dust/v2rayN.git
synced 2026-09-13 18:02:07 +03:00
Cache selected views in SimpleViewLocator
Add a `ConditionalWeakTable`-based view cache keyed by view model instance for `MsgViewModel`, `ClashProxiesViewModel`, and `ClashConnectionsViewModel` so repeated bindings reuse the same control. The locator now also handles missing registrations and null factory results more explicitly by returning descriptive `TextBlock` messages.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using Avalonia.Controls.Templates;
|
||||
using v2rayN.Desktop.ViewModels;
|
||||
using v2rayN.Desktop.Views;
|
||||
@@ -9,6 +10,7 @@ public class SimpleViewLocator : IDataTemplate
|
||||
private static readonly Lazy<SimpleViewLocator> _instance = new(() => new SimpleViewLocator());
|
||||
|
||||
private readonly Dictionary<Type, Func<Control?>> _locator = new();
|
||||
private readonly ConditionalWeakTable<object, Control> _cachedViews = new();
|
||||
|
||||
private SimpleViewLocator()
|
||||
{
|
||||
@@ -45,9 +47,18 @@ public class SimpleViewLocator : IDataTemplate
|
||||
return new TextBlock { Text = "No VM provided" };
|
||||
}
|
||||
|
||||
_locator.TryGetValue(data.GetType(), out var factory);
|
||||
var vmType = data.GetType();
|
||||
if (!_locator.TryGetValue(vmType, out var factory))
|
||||
{
|
||||
return new TextBlock { Text = $"VM Not Registered: {vmType}" };
|
||||
}
|
||||
|
||||
return factory?.Invoke() ?? new TextBlock { Text = $"VM Not Registered: {data.GetType()}" };
|
||||
if (ShouldCache(vmType))
|
||||
{
|
||||
return _cachedViews.GetValue(data, _ => CreateView(factory, vmType));
|
||||
}
|
||||
|
||||
return CreateView(factory, vmType);
|
||||
}
|
||||
|
||||
public bool Match(object? data)
|
||||
@@ -55,6 +66,18 @@ public class SimpleViewLocator : IDataTemplate
|
||||
return data is MyReactiveObject;
|
||||
}
|
||||
|
||||
private static bool ShouldCache(Type vmType)
|
||||
{
|
||||
return vmType == typeof(MsgViewModel)
|
||||
|| vmType == typeof(ClashProxiesViewModel)
|
||||
|| vmType == typeof(ClashConnectionsViewModel);
|
||||
}
|
||||
|
||||
private static Control CreateView(Func<Control?> factory, Type vmType)
|
||||
{
|
||||
return factory.Invoke() ?? new TextBlock { Text = $"View Factory Returned Null: {vmType}" };
|
||||
}
|
||||
|
||||
public void RegisterViewFactory<TViewModel>(Func<Control> factory) where TViewModel : class
|
||||
{
|
||||
_locator.Add(typeof(TViewModel), factory);
|
||||
|
||||
Reference in New Issue
Block a user