当前位置:必发365电子游戏 > Web前端 > 但是目前来看NanUI内部还有一些问题并没有得到解决
但是目前来看NanUI内部还有一些问题并没有得到解决
2019-12-19

NanUI for Winform从明日写博客公布到近些日子到手了和多朋友的青眼,首先感激大家的爱慕和支撑!请看前些天小编的博文《NanUI for Winform公布,让Winform分界面设计有所特别或者》。

有意中人问到小编是或不是思量开源NanUI,小编想回答是自然的。不过当前来看NanUI内部还应该有部分难点并未有博得消除,由此暂且不会怒放源代码。待那一个标题顺遂清除以后笔者会第有时间把NanUI的源码放到GitHub,请稍等片刻。

bifa365,那么,从今日起笔者会陆陆续续释放部分NanUI使用的豆蔻梢头部分小示例和源代码供感兴趣的相恋的人参谋把玩。任何关于NanUI的标题招待我们进群(群号:241088256)或留言与小编交换。

上边,起先今日的示范

必发365登录,NanUI for Winform 使用示例【第生龙活虎集】

山寨个代码编辑器

bifa365 1

2018年微软破天荒的发表了个吊炸天的开源代码编辑器VS Code,观看VS Code的目录构造可以见到,其实它也是依附CEF来拓宽付出的,使用的是名称为electron的框架。那么,下边小编将用NanUI山寨四个总结的Code编辑器达成对代码文件的新建、展开和封存操作,取名称叫NanUI代码编辑器。

NanUI代码编辑器使用的主题技艺有:

Bootstrap做响应式的页面吊炸天,尽管我们前些天要实行的小示例用不到响应式布局,不过引用进来就当CSS Clear用呢。此外四个CodeMirror作为网页端最精锐的代码编辑器,这一次通过NanUI,大家的Winform也将享受它推动的强硬功用。下边,笔者将分步讲明怎么着来山寨这一个代码编辑器。

在VS中新建Windows Application项目(前边称为主项目),然后在档案的次序->属性->调节和测验中关闭“运行VS承载进度”选项,因为经过试行,开启该采纳后不可能加载嵌入的网页能源。同有时间,开启“启用本机代码调节和测量试验选项”,因为ChromiumFX使用了PInvoke的章程调用,会有大多非驴非马的非托管错误,举个例子,笔者从前就碰着个纵然开动项目就报错的标题,开启了本机代码调节和测量试验后意识是QQ拼音输入法钩子的难点,点个忽视继续就可以平常调节和测验了。设置好后援用NanUI的库NetDimenison.NanUI.dll

bifa365 2

 

再新建一个类库项目(后边称为财富类型),在里边创设文件夹www,文件夹名字没有必要,随便就好,但要重申一点,html文件不能够在类库项目标根目录下,必得树立个文件夹来放置网页文档。将bootstrap和codemirror的html、css和js文件等拷贝进www目录,当然你也足以一贯从nuget上下载它们,只是要求把nuget得到的公文都拖到www里面,产生上面包车型客车公文结构。

bifa365 3

删除掉用不着的公文,从体系中解除或直接删除都行,剩下的内需用的项目都在质量窗口中把转变操作改成“嵌入的能源”。然后新建个静态类,名字随意取,里面新建个艺术来暴露财富类型的Assembly。

namespace NanUI.Demo.CodeEditor.Resources
{
    public static class SchemeHelper
    {
        public static System.Reflection.Assembly GetSchemeAssembley()
        {
            return System.Reflection.Assembly.GetExecutingAssembly();
        }
    }
}

新建这么些类的效果与利益是方便主项目登记财富类型里面包车型大巴程序集,假诺用这种方法来注册能源文件需求在主项目中援引进资金源类型。此外二个主意,能够直接在主项目中一贯运用Assembly.LoadFile加载财富类型,要是项目须要平时更新的话用那几个办法能够做到随时更新财富文件而不用重新安装整个软件,具体的用法会在今后的以身作则中牵线,在这里就非常的少说了。

如此,资源类型就弄好了。接下来的办事都将要主项目上进展了。在主项指标main函数里起先化NanUI。

namespace NanUI.Demo.CodeEditor
{
    using NetDimension.NanUI;

    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            UIStartupManager.UseSharedFramework = true;
            if (UIStartupManager.InitializeChromium())
            {
                //初始化成功,加载程序集内嵌的资源到运行时中
                UIStartupManager.RegisterEmbeddedScheme(Resources.SchemeHelper.GetSchemeAssembley());



                //启动主窗体
                Application.Run(new EditorForm());
            }


        }
    }
}

此中,Resources.SchemeHelper.GetSchemeAssembley(卡塔尔(英语:State of Qatar)方法正是从能源类型里面把Assembly加载过来。之后新建编辑器的主窗体EditorForm。EditorForm除了轻便的安装外,需其它增添多少个艺术来决定文件的新建、张开、保存等操作。

namespace NanUI.Demo.CodeEditor
{
    using NetDimension.NanUI;

    public partial class EditorForm : HtmlUIForm
    {

        internal bool isClean = true;
        internal bool isNew = true;

        internal string currentFilePath = string.Empty;


        public EditorForm()
            : base("embedded://www/main.html")
        {
            InitializeComponent();

            UI.GlobalObject.Add("hostEditor", new JsCodeEditorObject(this));
        }

        void SetEditorMode()
        {
            if (!string.IsNullOrEmpty(currentFilePath))
            {
                var fileInfo = new System.IO.FileInfo(currentFilePath);

                var ext = fileInfo.Extension;

                if (ext.IndexOf('.') == 0)
                {
                    ext = ext.Substring(1);
                    UI.ExecuteJavascript($"CodeEditor.changeCodeScheme('{ext}');");
                }
            }
        }

        //设置编辑器标题逻辑
        void SetEditorTitle()
        {
            if (isNew || string.IsNullOrEmpty(currentFilePath))
            {
                UI.ExecuteJavascript($"CodeEditor.setTitle('新建');");
            }
            else
            {
                var fileInfo = new System.IO.FileInfo(currentFilePath);
                UI.ExecuteJavascript($"CodeEditor.setTitle('{fileInfo.Name}');");
            }
        }
        //保存文件逻辑
        internal bool SaveFile()
        {
            var result = false;
            UI.EvaluateJavascript(@"CodeEditor.getContent()", (value, ex) =>
            {
                if (ex == null)
                {
                    var content = value.IsString ? value.StringValue : null;

                    if (content != null)
                    {

                        if (isNew)
                        {
                            var saveFileDialog = new SaveFileDialog()
                            {
                                AddExtension = true,
                                Filter = "支持的文件|*.txt;*.js;*.cs;*.html;*.htm;*.css;*.h;*.cpp;*.php;*.xml;*.vb",
                                OverwritePrompt = true
                            };
                            if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
                            {
                                currentFilePath = saveFileDialog.FileName;
                                result = true;

                            }
                        }

                        if (result)
                        {
                            System.IO.File.WriteAllText(currentFilePath, content, Encoding.UTF8);
                            isClean = true;
                            SetEditorMode();
                            SetEditorTitle();
                        }



                    }
                }
            });

            return result;
        }
        //新建文件逻辑
        internal void NewFile()
        {
            var continueFlag = true;

            if (!isClean)
            {
                var ret = MessageBox.Show(this, "文件已经更改,是否保存下先?", "提示", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

                if (ret == DialogResult.Yes)
                {
                    if (!SaveFile())
                    {
                        continueFlag = false;
                    }
                }
                else if (ret == DialogResult.Cancel)
                {
                    return;
                }
            }

            if (!continueFlag)
            {
                return;
            }

            isNew = true;
            isClean = true;


            UI.ExecuteJavascript(@"CodeEditor.setNew()");
            SetEditorTitle();



        }
        //打开文件逻辑
        internal string OpenFile()
        {
            var continueFlag = true;

            if (!isClean)
            {
                var ret = MessageBox.Show(this, "文件已经更改,是否保存下先?", "提示", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

                if (ret == DialogResult.Yes)
                {
                    if (!SaveFile())
                    {
                        continueFlag = false;
                    }
                }
                else if (ret == DialogResult.Cancel)
                {
                    return null;
                }
            }

            if (!continueFlag)
            {
                return null;
            }

            var content = string.Empty;

            var openDialog = new OpenFileDialog()
            {
                AddExtension = true,
                Filter = "支持的文件|*.txt;*.js;*.cs;*.html;*.htm;*.css;*.h;*.cpp;*.php;*.xml;*.vb"
            };

            if (openDialog.ShowDialog() == DialogResult.OK)
            {
                currentFilePath = openDialog.FileName;

                var fileInfo = new System.IO.FileInfo(currentFilePath);

                content = System.IO.File.ReadAllText(fileInfo.FullName);

                isNew = false;

                SetEditorMode();
                SetEditorTitle();
            }
            else
            {
                content = null;
            }

            return content;
        }
    }
}

 

上面入眼来了,以下内容将涉及C#操作网页内JS代码以至JS调用C#的点子等等,大旨正是中等对象JsCodeEditorObject。该对象世袭自ChromiumFX的JSObject对象,对JS有驾驭的恋人不会对JS的Object对象认为陌生,这里的JSObject对象和JS的Object对象实际很相同,也是含有了数据和议程的多个汇聚。如下所示,在其间注册了多个Function,这么些Function都是能够被网页端js调用的。

namespace NanUI.Demo.CodeEditor
{
    using Chromium.Remote;
    using NetDimension.NanUI;

    class JsCodeEditorObject : JSObject
    {

        EditorForm parentForm;

        internal JsCodeEditorObject(EditorForm parentForm)
        {
            this.parentForm = parentForm;

            AddFunction("newFile").Execute += JsCodeEditorObject_ExecuteNew;

            AddFunction("openFile").Execute += JsCodeEditorObject_ExecuteOpen;

            AddFunction("saveFile").Execute += JsCodeEditorObject_ExecuteSave;

            AddFunction("setClean").Execute += JsCodeEditorObject_ExecuteSetClean;
        }





        private void JsCodeEditorObject_ExecuteSetClean(object sender, Chromium.Remote.Event.CfrV8HandlerExecuteEventArgs e)
        {
            if (e.Arguments.Length > 0)
            {

                parentForm.isClean = e.Arguments.First(p => p.IsBool).BoolValue;
            }
        }

        private void JsCodeEditorObject_ExecuteSave(object sender, Chromium.Remote.Event.CfrV8HandlerExecuteEventArgs e)
        {
            var result  = parentForm.SaveFile();

            e.SetReturnValue(CfrV8Value.CreateBool(result));

        }

        private void JsCodeEditorObject_ExecuteOpen(object sender, Chromium.Remote.Event.CfrV8HandlerExecuteEventArgs e)
        {
            var result = parentForm.OpenFile();

            if (result != null)
            {
                e.SetReturnValue(CfrV8Value.CreateString(result));

            }
            else
            {
                e.SetReturnValue(CfrV8Value.CreateNull());
            }
        }

        private void JsCodeEditorObject_ExecuteNew(object sender, Chromium.Remote.Event.CfrV8HandlerExecuteEventArgs e)
        {
            parentForm.NewFile();
        }
    }
}

如上边代码中所展现的,这些类注册了newFile, openFile, saveFile和setClean多少个方式供网页端js调用。再折回来地点EditorForm的代码,有那样黄金时代行:

UI.GlobalObject.Add("hostEditor", new JsCodeEditorObject(this));

那行代码的左右就是将我们的中档对象JsCodeEditorObject实例化后传到浏览器的JS境况中,何况取了个新名字称为“hostEditor”,那样,我们就可见在网页境况中用js实践上面包车型客车多少个法子了。

当网页端js调用地方这几个情势的时候其实会举行到艾德itorForm中相应的操作逻辑,如此就兑现了js与c#情状的互相。C#与js意况相互与之相比较要轻便得多,举个例子EdiorForm中的SetEditorTitle方法中,通过UI.ExecuteJavascript方法就足以试行web情形中的js代码或艺术。

UI.ExecuteJavascript($"CodeEditor.setTitle('新建');");

如上那行代码,调用了js的艺术CodeEditor.setTitle来设置编辑器的标题。那么,假使必要进行js代码并再次回到相应代码,就得利用UI.EvaluateJavascript方法。该办法第多个参数为js代码,第3个参数为进行js代码后的回调,它是多少个有多个参数的action对象,第一个参数为回调的重临值,第三个参数是exception对象,假若js代码卓殊,那么第4个对象exception就带有了错误音信,准确实践时,excepiton对象回来null。

UI.EvaluateJavascript(@"CodeEditor.getContent()", (value, ex) =>
{
    if (ex == null)
    {
        var content = value.IsString ? value.StringValue : null; //value对象是CfrV8Value对象,内置了各种数据转换的方法。

        //其他逻辑
    }
});

 

有了下面的代码要点,大家应该早已清楚C#和JS之间的相互情势和JS于C#里面的互相的措施了。不问可见,C#与NanUI的js交互作用,无再次回到值的用UI.ExecuteJavascript方法,有重回值的用UI.EvaluateJavascript。除了那八个措施外,能够用UI.AddFunction方法来向来在js景况中注册C#的议程,方法大家自行钻研在这里不再演说。要是js须要与C#里面包车型大巴互相,通过编写制定世襲JSObject的中间对象注册方式或数额对象,就能够兑现。

那正是说,NanUI的演示第朝气蓬勃集就那样讲罢了,借使不明了请留言给本人或进群(群号:241088256)交换,感激大家关怀。

 


NanUI for .NET Winform种类目录


由此了那一个多星期的调动与修补,NanUI for .NET Winform的稳固版已经昭示。应广大群友的渴求,现已将NanUI的全部代码开源。

GitHub: 

Release: 


 

但是目前来看NanUI内部还有一些问题并没有得到解决。 假若你赏识NanUI项目,你可以涉足到NanUI的付出中来,当然你也足以更直接了当的支撑笔者的办事,使用支付宝或Wechat扫描上边二维码请自个儿喝蓬蓬勃勃杯热腾腾的咖啡。

bifa365 4

支付宝转账

bifa365 5

Wechat转载


 

此外,打个广告,继承NanUI分界面设计与接口开荒(收取工资)。

案例显示

某谈心应用

bifa365 6

某商厦里面办公室系统

bifa365 7

bifa365 8