用于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

}

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐