diff --git a/v2rayN/v2rayN.Desktop/Common/SimpleViewLocator.cs b/v2rayN/v2rayN.Desktop/Common/SimpleViewLocator.cs index 8b4328f5..f589a245 100644 --- a/v2rayN/v2rayN.Desktop/Common/SimpleViewLocator.cs +++ b/v2rayN/v2rayN.Desktop/Common/SimpleViewLocator.cs @@ -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 _instance = new(() => new SimpleViewLocator()); private readonly Dictionary> _locator = new(); + private readonly ConditionalWeakTable _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 factory, Type vmType) + { + return factory.Invoke() ?? new TextBlock { Text = $"View Factory Returned Null: {vmType}" }; + } + public void RegisterViewFactory(Func factory) where TViewModel : class { _locator.Add(typeof(TViewModel), factory);