You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
3.3 KiB
102 lines
3.3 KiB
using ReactiveUI;
|
|
using Splat;
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
namespace MyAvaloniaApp.Views;
|
|
|
|
/// <summary>
|
|
/// 视图定位器,用于将 ViewModel 映射到对应的 View
|
|
/// 支持依赖注入创建 View 实例
|
|
/// </summary>
|
|
public class ViewLocator : IViewLocator
|
|
{
|
|
/// <summary>
|
|
/// 根据 ViewModel 类型解析对应的 View
|
|
/// </summary>
|
|
public IViewFor? ResolveView<T>(T? viewModel, string? contract = null)
|
|
{
|
|
if (viewModel == null)
|
|
{
|
|
Debug.WriteLine("[ViewLocator] ViewModel is null");
|
|
return null;
|
|
}
|
|
|
|
var viewModelType = viewModel.GetType();
|
|
Debug.WriteLine($"[ViewLocator] Resolving View for ViewModel: {viewModelType.FullName}");
|
|
|
|
// 将 ViewModel 名称转换为 View 名称
|
|
var viewModelName = viewModelType.Name; // 只获取类名
|
|
|
|
// 处理多种命名模式
|
|
var viewName = viewModelName
|
|
.Replace("PageViewModel", "PageView")
|
|
.Replace("ViewModel", "View");
|
|
|
|
Debug.WriteLine($"[ViewLocator] Looking for View: {viewName}");
|
|
Debug.WriteLine($"[ViewLocator] ViewModel Namespace: {viewModelType.Namespace}");
|
|
|
|
// 获取与 ViewModel 在同一命名空间下的 View
|
|
var assembly = viewModelType.Assembly;
|
|
var targetNamespace = viewModelType.Namespace?.Replace(".ViewModels", ".Views");
|
|
Debug.WriteLine($"[ViewLocator] Target namespace: {targetNamespace}");
|
|
|
|
var viewType = assembly.GetTypes()
|
|
.FirstOrDefault(t => t.Name == viewName && t.Namespace == targetNamespace);
|
|
|
|
if (viewType == null)
|
|
{
|
|
Debug.WriteLine($"[ViewLocator] View not found: {viewName} in {targetNamespace}");
|
|
return null;
|
|
}
|
|
|
|
Debug.WriteLine($"[ViewLocator] Found View: {viewType.FullName}");
|
|
|
|
IViewFor? view = null;
|
|
|
|
// 尝试从依赖注入容器获取 View 实例
|
|
try
|
|
{
|
|
var serviceProvider = Locator.Current.GetService<IServiceProvider>();
|
|
if (serviceProvider != null)
|
|
{
|
|
view = serviceProvider.GetService(viewType) as IViewFor;
|
|
if (view != null)
|
|
{
|
|
Debug.WriteLine($"[ViewLocator] Created View from DI: {view.GetType().FullName}");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine($"[ViewLocator] Failed to get View from DI: {ex.Message}");
|
|
}
|
|
|
|
// 如果 DI 中没有,使用 Activator 创建
|
|
if (view == null)
|
|
{
|
|
try
|
|
{
|
|
view = Activator.CreateInstance(viewType) as IViewFor;
|
|
if (view != null)
|
|
{
|
|
Debug.WriteLine($"[ViewLocator] Created View with Activator: {view.GetType().FullName}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine($"[ViewLocator] Failed to create View with Activator: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
if (view == null)
|
|
{
|
|
Debug.WriteLine("[ViewLocator] Failed to create View instance");
|
|
}
|
|
|
|
return view;
|
|
}
|
|
}
|
|
|
|
|