用于MVVM设计模式的ViewModel基类;
参考WPF的模式,修改为Avalonia适用的基类;
供学习使用,大家可以评论或私信我一块学习成长。
using Avalonia.Controls;
using ReactiveUI;
namespace AvaloniaClient.ViewModels;
public class ViewModelBase : ReactiveObject
{
//程序的主命名空间
public string UINameSapce = "";
//类名
public string UIElementName = "";
public Avalonia.Controls.Control UIElement { get; set; }
private System.Type UIType;
/// <summary>
/// ViewModel基类 需要传UI界面的全名(FullName)参数
/// </summary>
/// <param name="uiType">UI界面的类型</param>
public ViewModelBase(System.Type uiType)
{
try
{
UIType = uiType;
UINameSapce = uiType.Namespace;
SetUIElement();
UIElement.DataContext = this;
Avalonia.Input.InputMethod.SetIsInputMethodEnabled(UIElement, false);
}
catch (System.Exception ex)
{
throw ex;
}
}
/// <summary>
/// ViewModel基类,直接传入UI界面对象
/// </summary>
/// <param name="ui"></param>
public ViewModelBase(Avalonia.Controls.Control ui)
{
try
{
UIType = ui.GetType();
UINameSapce = UIType.Namespace;
UIElementName = UIType.FullName;
UIElement = ui;
UIElement.Loaded += Page_Loaded;
UIElement.Unloaded += Page_Unloaded;
UIElement.DataContext = this;
Avalonia.Input.InputMethod.SetIsInputMethodEnabled(UIElement, false);
}
catch (System.Exception ex)
{
throw ex;
}
}
#region 通过反射创建对应的UI元素
/// <summary>
/// 页面加载时触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void Page_Loaded(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
}
/// <summary>
/// 页面退出时触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected virtual void Page_Unloaded(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
}
/// <summary>
/// 根据VM名称,反射对应类型的UI实例
/// </summary>
public void SetUIElement()
{
System.Type childType = this.GetType();//获取子类的类型
UIElementName = this.GetType().FullName;
UIElement = (Avalonia.Controls.Control)GetElement();
UIElement.Loaded += Page_Loaded;
UIElement.Unloaded += Page_Unloaded;
}
/// <summary>
/// 用UI全名称(FullName)进行反射UI实例
/// </summary>
/// <typeparam name="E"></typeparam>
/// <param name="UIElementFullName"></param>
/// <returns></returns>
public object GetElement()
{
if (UIType != null)
{
return System.Activator.CreateInstance(UIType);
}
else
{
throw new System.Exception("UIType为空");
}
}
/// <summary>
/// 根据窗口全名获取窗口类型 -对动态加载窗口不友好、已弃用
/// </summary>
/// <param name="fullName"></param>
/// <returns></returns>
public System.Type GetFormType(string fullName)
{
System.Reflection.Assembly assembly = System.Reflection.Assembly.Load(UINameSapce);
System.Type type = assembly.GetType(fullName, true, false);
return type;
}
#endregion
#region 窗体操作
/// <summary>
/// 显示窗口
/// </summary>
/// <exception cref="System.Exception"></exception>
public void Show()
{
if (UIElement is Avalonia.Controls.Window)
{
Avalonia.Threading.Dispatcher.UIThread.Invoke(new System.Action(() =>
{
(UIElement as Avalonia.Controls.Window).Show();
}));
}
else
{
throw new System.Exception("元素类型不正确");
}
}
/// <summary>
/// 模态对话框显示
/// </summary>
/// <returns></returns>
/// <exception cref="System.Exception"></exception>
public bool ShowDialog()
{
if (UIElement is Avalonia.Controls.Window)
{
var res = (UIElement as Avalonia.Controls.Window).ShowDialog<bool>((VM_MainWindow.Instance.UIElement as Window));
res.Wait();
return res.Result;
}
else
{
throw new System.Exception("元素类型不正确");
}
}
/// <summary>
/// 窗口关闭
/// </summary>
/// <exception cref="System.Exception"></exception>
public void Close()
{
if (UIElement is Avalonia.Controls.Window)
{
Avalonia.Threading.Dispatcher.UIThread.Invoke(new System.Action(() =>
{
(UIElement as Avalonia.Controls.Window).Close();
}));
}
else
{
throw new System.Exception("元素类型不正确");
}
}
/// <summary>
/// 窗口隐藏
/// </summary>
/// <exception cref="System.Exception"></exception>
public void Hide()
{
if (UIElement is Avalonia.Controls.Window)
{
Avalonia.Threading.Dispatcher.UIThread.Invoke(new System.Action(() =>
{
(UIElement as Avalonia.Controls.Window).Hide();
}));
}
else
{
throw new System.Exception("元素类型不正确");
}
}
#endregion
#region 异步线程
/// <summary>
/// 异步方法执行事件
/// </summary>
public void AsyncLoad(System.Action action)
{
System.IAsyncResult result = action.BeginInvoke((iar) =>
{
}, null);
}
/// <summary>
/// 异步方法执行事件 带回调方法
/// </summary>
public void AsyncLoad(System.Action action, System.Action callback)
{
System.IAsyncResult result = action.BeginInvoke((iar) =>
{
this.DoMenthodByDispatcher(callback);
}, null);
}
/// <summary>
/// 异步方法执行事件 带参数及带回调方法
/// </summary>
public void AsyncLoad<T>(System.Action<T> action, T para, System.Action callback)
{
System.IAsyncResult result = action.BeginInvoke(para, (iar) =>
{
this.DoMenthodByDispatcher(callback);
}, null);
}
/// <summary>
/// 异步方法执行事件 带参数及带回调方法
/// </summary>
public void AsyncLoad<T, R>(System.Func<T, R> action, T para, System.Action<R> callback)
{
System.IAsyncResult result = action.BeginInvoke(para, (iar) =>
{
var res = action.EndInvoke(iar);
this.DoMenthodByDispatcher<R>(callback, res);
}, null);
}
/// <summary>
/// 异步方法执行事件 带回调方法
/// </summary>
/// <typeparam name="R"></typeparam>
/// <param name="action"></param>
/// <param name="callback"></param>
public void AsyncLoad<R>(System.Func<R> action, System.Action<R> callback)
{
System.IAsyncResult result = action.BeginInvoke((iar) =>
{
var res = action.EndInvoke(iar);
this.DoMenthodByDispatcher<R>(callback, res);
}, null);
}
/// <summary>
/// 使用UI线程执行Action 带参数 默认 异步(BeginInvoke)执行
/// </summary>
/// <typeparam name="T">泛型参数</typeparam>
/// <param name="action">执行的方法</param>
/// <param name="obj">参数</param>
/// <param name="isAsync">是否异步 true-异步 false-同步</param>
public void DoMenthodByDispatcher<T>(System.Action<T> action, T obj, bool isAsync = true)
{
if (isAsync)
{
Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(new System.Action(() =>
{
action(obj);
}));
}
else
{
Avalonia.Threading.Dispatcher.UIThread.Invoke(new System.Action(() =>
{
action(obj);
}));
}
}
/// <summary>
///使用UI线程执行Action 默认 异步(BeginInvoke)执行
/// </summary>
/// <param name="action"></param>
/// <param name="isAsync">是否异步 true-异步 false-同步</param>
public void DoMenthodByDispatcher(System.Action action, bool isAsync = true)
{
if (isAsync)
{
Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(new System.Action(() =>
{
action();
}));
}
else
{
Avalonia.Threading.Dispatcher.UIThread.Invoke(new System.Action(() =>
{
action();
}));
}
}
#endregion
}