黄色电影一区二区,韩国少妇自慰A片免费看,精品人妻少妇一级毛片免费蜜桃AV按摩师 ,超碰 香蕉

基于WPF制作一個可編程畫板

基于wpf制作一個可編程畫板

 

先上一張效果動圖

同樣老規(guī)矩,先上源碼地址:https://gitee.com/akwkevin/aistudio.-wpf.-diagram

簡單使用,自定義一個text模塊的代碼如下

code?=?@"using?system;
namespace?aistudio.wpf.csharpscript
{
????public?class?writer
????{???
????????public?string?stringvalue{?get;?set;}?=?""welcome?to?aistudio.wpf.diagram"";
????????public?string?execute()
????????{
????????????return?stringvalue;
????????}
????}
}";

是不是很簡單。

 

本次擴展的主要內容

1.可編程模塊,使用c#語言。

2.控制臺打印控件,可以打印程序中的console.writeline數(shù)據(jù)

3.為了便于大家使用,寫了一個box工廠分配box的數(shù)據(jù)流向效果圖。

可編程模塊的實現(xiàn)原理

使用microsoft.codeanalysis.csharp.scripting對代碼進行編譯,生成assembly,然后對assembly反射獲得對象,對象內部固定有一個execute方法,每次掃描的時候執(zhí)行即可。

1.編譯使用的using,必須添加引用集,為了省事,把整個程序的reference都放入進行編譯,獲得引用的核心代碼如下:

var?references?=?appdomain.currentdomain.getassemblies().where(p?=>?!p.isdynamic?&&?!string.isnullorempty(p.location)).select(x?=>?metadatareference.createfromfile(x.location)).tolist();
//costura.fody壓縮后,無location,讀取資源文件中的reference
foreach?(var?assemblyembedded?in?appdomain.currentdomain.getassemblies().where(p?=>?!p.isdynamic?&&?string.isnullorempty(p.location)))
{
????using?(var?stream?=?assembly.getentryassembly().getmanifestresourcestream($"costura.{assemblyembedded.getname().name.tolowerinvariant()}.dll.compressed"))
????{
????????if?(stream?!=?null)
????????{
????????????using?(var?compressstream?=?new?deflatestream(stream,?compressionmode.decompress))
????????????{
????????????????var?memstream?=?new?memorystream();
????????????????copyto(compressstream,?memstream);
????????????????memstream.position?=?0;
????????????????references.add(metadatareference.createfromstream(memstream));
????????????}
????????}
????}
}

2.動態(tài)編譯的代碼的核心代碼如下:

public?static?assembly?generateassemblyfromcode(string?code,?out?string?message)
{
????assembly?assembly?=?null;
????message?=?"";
????//?叢代碼中轉換表達式樹
????syntaxtree?syntaxtree?=?csharpsyntaxtree.parsetext(code);
????//?隨機程序集名稱
????string?assemblyname?=?path.getrandomfilename();
????//?引用
????//?創(chuàng)建編譯對象
????csharpcompilation?compilation?=?csharpcompilation.create(assemblyname,?new[]?{?syntaxtree?},?references,?new?csharpcompilationoptions(outputkind.dynamicallylinkedlibrary));
????using?(var?ms?=?new?memorystream())
????{
????????//?將編譯好的il代碼放入內存流
????????emitresult?result?=?compilation.emit(ms);
????????//?編譯失敗,提示
????????if?(!result.success)
????????{
????????????ienumerable<diagnostic>?failures?=?result.diagnostics.where(diagnostic?=>
????????????????????????diagnostic.iswarningaserror?||
????????????????????????diagnostic.severity?==?diagnosticseverity.error).tolist();
????????????foreach?(diagnostic?diagnostic?in?failures)
????????????{
????????????????message?+=?$"{diagnostic.id}:?{diagnostic.getmessage()}";
????????????????console.writeline(message);
????????????}
????????}
????????else
????????{
????????????//?編譯成功,從內存中加載編譯好的程序集
????????????ms.seek(0,?seekorigin.begin);
????????????assembly?=?assembly.load(ms.toarray());
????????}
????}
????return?assembly;
}

3.獲得編譯后的程序集,以及執(zhí)行。

//?反射獲取程序集中?的類
type?type?=?assembly.gettypes().firstordefault(p?=>?p.fullname.startswith("aistudio.wpf"));???//assembly.gettype("aistudio.wpf.csharpscript.write");
//?創(chuàng)建該類的實例
object?obj?=?activator.createinstance(type);
//?通過反射方式調用類中的方法。
var?result?=?type.invokemember("execute",
????bindingflags.default?|?bindingflags.invokemethod,
????null,
????obj,
????new?object[]?{?});

代碼編輯模塊的實現(xiàn)

選擇avalonedit控件,另外為了使用vs2019_dark的黑色皮膚,引用官方demo中的hl和texteditlib實現(xiàn)自定義換膚。

官方demo的換膚寫的超級復雜,看不懂,但是我們只要理解換膚的核心部分就是動態(tài)資源字典,因此我簡化下,改進后的核心換膚代碼如下:

public?class?texteditorthemehelper
{
????static?dictionary<string,?resourcedictionary>?themedictionary?=?new?dictionary<string,?resourcedictionary>();
????public?static?list<string>?themes?=?new?list<string>()?{?"dark",?"light",?"trueblue",?"vs2019_dark"?};
????public?static?string?currenttheme?{?get;?set;?}
????static?texteditorthemehelper()
????{
????????var?resource?=?new?resourcedictionary?{?source?=?new?uri("/texteditlib;component/themes/lightbrushs.xaml",?urikind.relativeorabsolute)?};
????????themedictionary.add("light",?resource);
????????resource?=?new?resourcedictionary?{?source?=?new?uri("/texteditlib;component/themes/darkbrushs.xaml",?urikind.relativeorabsolute)?};
????????themedictionary.add("dark",?resource);
????????application.current.resources.mergeddictionaries.add(resource);
????}
????///?<summary>
????///?設置主題
????///?</summary>
????///?<param?name="theme"></param>
????public?static?void?setcurrenttheme(string?theme)
????{
????????onappthemechanged(theme);//切換到vs2019_dark
????????currenttheme?=?theme;
????}
????///?<summary>
????///?invoke?this?method?to?apply?a?change?of?theme?to?the?content?of?the?document
????///?(eg:?adjust?the?highlighting?colors?when?changing?from?"dark"?to?"light"
????///??????with?current?text?document?loaded.)
????///?</summary>
????internal?static?void?onappthemechanged(string?theme)
????{
????????themedhighlightingmanager.instance.setcurrenttheme(theme);
????????if?(themedictionary.containskey(theme))
????????{
????????????foreach?(var?key?in?themedictionary[theme].keys)
????????????{
????????????????applytodynamicresource(key,?themedictionary[theme][key]);
????????????}
????????}
????????//?does?this?highlighting?definition?have?an?associated?highlighting?theme?
????????else?if?(themedhighlightingmanager.instance.currenttheme.hltheme?!=?null)
????????{
????????????//?a?highlighting?theme?with?globalstyles?
????????????//?apply?these?styles?to?the?resource?keys?of?the?editor
????????????foreach?(var?item?in?themedhighlightingmanager.instance.currenttheme.hltheme.globalstyles)
????????????{
????????????????switch?(item.typename)
????????????????{
????????????????????case?"defaultstyle":
????????????????????????applytodynamicresource(texteditlib.themes.resourcekeys.editorbackground,?item.backgroundcolor);
????????????????????????applytodynamicresource(texteditlib.themes.resourcekeys.editorforeground,?item.foregroundcolor);
????????????????????????break;
????????????????????case?"currentlinebackground":
????????????????????????applytodynamicresource(texteditlib.themes.resourcekeys.editorcurrentlinebackgroundbrushkey,?item.backgroundcolor);
????????????????????????applytodynamicresource(texteditlib.themes.resourcekeys.editorcurrentlineborderbrushkey,?item.bordercolor);
????????????????????????break;
????????????????????case?"linenumbersforeground":
????????????????????????applytodynamicresource(texteditlib.themes.resourcekeys.editorlinenumbersforeground,?item.foregroundcolor);
????????????????????????break;
????????????????????case?"selection":
????????????????????????applytodynamicresource(texteditlib.themes.resourcekeys.editorselectionbrush,?item.backgroundcolor);
????????????????????????applytodynamicresource(texteditlib.themes.resourcekeys.editorselectionborder,?item.bordercolor);
????????????????????????break;
????????????????????case?"hyperlink":
????????????????????????applytodynamicresource(texteditlib.themes.resourcekeys.editorlinktextbackgroundbrush,?item.backgroundcolor);
????????????????????????applytodynamicresource(texteditlib.themes.resourcekeys.editorlinktextforegroundbrush,?item.foregroundcolor);
????????????????????????break;
????????????????????case?"nonprintablecharacter":
????????????????????????applytodynamicresource(texteditlib.themes.resourcekeys.editornonprintablecharacterbrush,?item.foregroundcolor);
????????????????????????break;
????????????????????default:
????????????????????????throw?new?system.argumentoutofrangeexception("globalstyle?named?'{0}'?is?not?supported.",?item.typename);
????????????????}
????????????}
????????}
????}
????///?<summary>
????///?re-define?an?existing?<seealso?cref="solidcolorbrush"/>?and?backup?the?originial?color
????///?as?it?was?before?the?application?of?the?custom?coloring.
????///?</summary>
????///?<param?name="key"></param>
????///?<param?name="newcolor"></param>
????private?static?void?applytodynamicresource(componentresourcekey?key,?color??newcolor)
????{
????????if?(application.current.resources[key]?==?null?||?newcolor?==?null)
????????????return;
????????//?re-coloring?works?with?solidcolorbrushs?linked?as?dynamicresource
????????if?(application.current.resources[key]?is?solidcolorbrush)
????????{
????????????//backupdynresources.add(resourcename);
????????????var?newcolorbrush?=?new?solidcolorbrush((color)newcolor);
????????????newcolorbrush.freeze();
????????????application.current.resources[key]?=?newcolorbrush;
????????}
????}
????private?static?void?applytodynamicresource(object?key,?object?newvalue)
????{
????????if?(application.current.resources[key]?==?null?||?newvalue?==?null)
????????????return;
????????application.current.resources[key]?=?newvalue;
????}
}

使用方法:

texteditorthemehelper.setcurrenttheme("vs2019_dark");

或者 texteditorthemehelper.setcurrenttheme("trueblue");

或者 texteditorthemehelper.setcurrenttheme("dark");

或者 texteditorthemehelper.setcurrenttheme("light");

是不是超級簡單。

代碼編輯模塊的編譯與測試

wpf打印控制臺數(shù)據(jù)

///控制臺打印方法支持切換運行輸出方法console.setout,核心代碼如下:
public?class?consolewriter?:?textwriter
{
????private?readonly?action<string>?_write;
????private?readonly?action<string>?_writeline;
????private?readonly?action<string,?string,?string,?int>?_writecallerinfo;
????public?consolewriter()
????{
????}
????///?<summary>
????///?console?輸出重定向
????///?</summary>
????///?<param?name="write">日志方法委托(針對于?write)</param>
????///?<param?name="writeline">日志方法委托(針對于?writeline)</param>
????public?consolewriter(action<string>?write,?action<string>?writeline,?action<string,?string,?string,?int>?writecallerinfo)
????{
????????_write?=?write;
????????_writeline?=?writeline???write;
????????_writecallerinfo?=?writecallerinfo;
????}
????///?<summary>
????///?console?輸出重定向
????///?</summary>
????///?<param?name="write">日志方法委托(針對于?write)</param>
????///?<param?name="writeline">日志方法委托(針對于?writeline)</param>
????public?consolewriter(action<string>?write,?action<string>?writeline)
????{
????????_write?=?write;
????????_writeline?=?writeline;
????}
????///?<summary>
????///?console?輸出重定向
????///?</summary>
????///?<param?name="write">日志方法委托</param>
????public?consolewriter(action<string>?write)
????{
????????_write?=?write;
????????_writeline?=?write;
????}
????///?<summary>
????///?console?輸出重定向(帶調用方信息)
????///?</summary>
????///?<param?name="write">日志方法委托(后三個參數(shù)為?callerfilepath、callermembername、callerlinenumber)</param>
????public?consolewriter(action<string,?string,?string,?int>?write)
????{
????????_writecallerinfo?=?write;
????}
????///?<summary>
????///?使用?utf-16?避免不必要的編碼轉換
????///?</summary>
????public?override?encoding?encoding?=>?encoding.unicode;
????///?<summary>
????///?最低限度需要重寫的方法
????///?</summary>
????///?<param?name="value">消息</param>
????public?override?void?write(string?value)
????{
????????if?(_writecallerinfo?!=?null)
????????{
????????????writewithcallerinfo(value);
????????????return;
????????}
????????_write(value);
????}
????///?<summary>
????///?為提高效率直接處理一行的輸出
????///?</summary>
????///?<param?name="value">消息</param>
????public?override?void?writeline(string?value)
????{
????????if?(_writecallerinfo?!=?null)
????????{
????????????writewithcallerinfo(value);
????????????return;
????????}
????????_writeline(value);
????}
????///?<summary>
????///?帶調用方信息進行寫消息
????///?</summary>
????///?<param?name="value">消息</param>
????private?void?writewithcallerinfo(string?value)
????{
????????//3、system.console.writeline?->?2、system.io.textwriter?+?synctextwriter.writeline?->?1、dotnet.utilities.consolehelper.consolewriter.writeline?->?0、dotnet.utilities.consolehelper.consolewriter.writewithcallerinfo
????????var?callinfo?=?classhelper.getmethodinfo(4);
????????_writecallerinfo(value,?callinfo?.filename,?callinfo?.methodname,?callinfo?.linenumber????0);
????}
????public?override?void?close()
????{
????????var?standardoutput?=?new?streamwriter(console.openstandardoutput());
????????standardoutput.autoflush?=?true;
????????console.setout(standardoutput);
????????base.close();
????}
}

使用:

consolewriter consolewriter = new consolewriter(_write, _writeline);

console.setout(consolewriter);

動態(tài)編譯模塊的輸入輸出自動生成

1.輸入輸出模塊:public string value{ get; set;}

2.輸入模塊:public string value{private get; set;}

3.輸出模塊:public string value{get;private set;}

4.與外部交互模塊:private string value{ get; set;} ,必須同名同屬性。 核心代碼如下:

public?static?dictionary<string,?list<propertyinfo>>?getpropertyinfo(type?type)
{
????dictionary<string,?list<propertyinfo>>?puts?=?new?dictionary<string,?list<propertyinfo>>()
????{
????????{"input",?new?list<propertyinfo>()?},
????????{"output",?new?list<propertyinfo>()?},
????????{"input_output",?new?list<propertyinfo>()?},
????????{"inner",?new?list<propertyinfo>()?}
????};
????try
????{
????????foreach?(system.reflection.propertyinfo?info?in?type.getproperties(bindingflags.public?|?bindingflags.instance))
????????{
????????????if?(info.canread?&&?info.canwrite)
????????????{
????????????????if?(info.setmethod.ispublic?&&?info.getmethod.ispublic)
????????????????{
????????????????????puts["input_output"].add(info);
????????????????}
????????????????else?if?(info.setmethod.ispublic)
????????????????{
????????????????????puts["input"].add(info);
????????????????}
????????????????else?if?(info.getmethod.ispublic)
????????????????{
????????????????????puts["output"].add(info);
????????????????}
????????????}
????????????else?if?(info.canread)
????????????{
????????????????if?(info.getmethod.ispublic)
????????????????{
????????????????????puts["output"].add(info);
????????????????}
????????????}
????????}
????????foreach?(system.reflection.propertyinfo?info?in?type.getproperties(bindingflags.nonpublic?|?bindingflags.instance))
????????{
????????????if?(info.canread)
????????????{
????????????????puts["inner"].add(info);
????????????}
????????}
????}
????catch?(exception?ex)
????{
????}
????return?puts;
}

最后介紹一下demo的實現(xiàn)

1#.int整數(shù)模塊,界面定義一個textbox綁定int模塊的輸入管腳。 2#.box產(chǎn)生模塊,如果內部數(shù)組為空,那么按照輸入管腳的數(shù)量初始化一個容量為輸入整數(shù)數(shù)量的數(shù)組(隨機顏色與形狀),然后把數(shù)據(jù)放到輸出管腳,當數(shù)據(jù)被取走后,下一個數(shù)據(jù)再次放到輸出管腳。 3#.bool模塊,為false的時候按照顏色進行分配,為true的時候按照形狀進行分配。4#.box分配模塊,當輸入管腳為空的時候,2#模塊的輸出可以移動到4#的輸入管腳,移動時間為1s,移動完成后,清除2#模塊的輸出。同時把數(shù)據(jù)按照顏色或者形狀分配到輸出,同時把輸入管腳清除。 按照顏色分配時: (1.如果顏色為紅色,那么輸出到1號 (2.如果顏色為橙色,那么輸出到2號 (3.如果顏色為黃色,那么輸出到3號 (4.如果顏色為綠色,那么輸出到4號 (5.如果顏色為青色,那么輸出到5號 (6.如果顏色為藍色,那么輸出到6號 (7.如果顏色為紫色,那么輸出到7號 按照形狀分配時: (1.如果形狀為圓形,那么輸出到1號 (2.如果形狀為三角形,那么輸出到2號 (3.如果形狀為方形,那么輸出到3號 (4.如果形狀為菱形,那么輸出到4號 (5.如果形狀為梯形,那么輸出到5號 (6.如果形狀為五角星,那么輸出到6號 (7.如果形狀為六邊形,那么輸出到7號 6#.有兩個紅色|圓形收集器(7#,8#),按兩個容器中的數(shù)量比較反饋,均勻分配到這兩個收集器中。 9#,10#,11#,12#,13#,14#按照管腳取走數(shù)據(jù)即可。

以上就是基于wpf制作一個可編程畫板的詳細內容,更多關于wpf可編程畫板的資料請關注碩編程其它相關文章!

下一節(jié):c#中@字符d是個什么意思

c# 教程

相關文章