mirror of
https://github.com/2dust/v2rayN.git
synced 2026-10-26 15:15:04 +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 Avalonia.Controls.Templates;
|
||||||
using v2rayN.Desktop.ViewModels;
|
using v2rayN.Desktop.ViewModels;
|
||||||
using v2rayN.Desktop.Views;
|
using v2rayN.Desktop.Views;
|
||||||
@@ -9,6 +10,7 @@ public class SimpleViewLocator : IDataTemplate
|
|||||||
private static readonly Lazy<SimpleViewLocator> _instance = new(() => new SimpleViewLocator());
|
private static readonly Lazy<SimpleViewLocator> _instance = new(() => new SimpleViewLocator());
|
||||||
|
|
||||||
private readonly Dictionary<Type, Func<Control?>> _locator = new();
|
private readonly Dictionary<Type, Func<Control?>> _locator = new();
|
||||||
|
private readonly ConditionalWeakTable<object, Control> _cachedViews = new();
|
||||||
|
|
||||||
private SimpleViewLocator()
|
private SimpleViewLocator()
|
||||||
{
|
{
|
||||||
@@ -45,9 +47,18 @@ public class SimpleViewLocator : IDataTemplate
|
|||||||
return new TextBlock { Text = "No VM provided" };
|
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)
|
public bool Match(object? data)
|
||||||
@@ -55,6 +66,18 @@ public class SimpleViewLocator : IDataTemplate
|
|||||||
return data is MyReactiveObject;
|
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
|
public void RegisterViewFactory<TViewModel>(Func<Control> factory) where TViewModel : class
|
||||||
{
|
{
|
||||||
_locator.Add(typeof(TViewModel), factory);
|
_locator.Add(typeof(TViewModel), factory);
|
||||||
|
|||||||
Reference in New Issue
Block a user