1. 程式人生 > 實用技巧 >幹!垃圾微軟!釋出我的Netcore跨平臺UI框架 CPF

幹!垃圾微軟!釋出我的Netcore跨平臺UI框架 CPF

什麼鬼,我的CPF快寫好了,你居然也要搞跨平臺UI框架?什麼Maui? 之前怎麼不早說要搞跨平臺UI框架呢?看到谷歌搞flutter眼紅了?明年年底釋出?又搞這種追別人屁股的爛事情。

什麼MVU模式?模仿Dart?用C#程式碼直接寫UI的模式和我的CPF很像啊。

當初我考慮過XML,Json來描述UI,但是我感覺這些都是多餘的累贅,而且還需要學習語法,感覺Xaml很囉嗦,如果有設計器的話,直接生成對應的UI程式碼不是更直接?而且用XML、Json需要多消耗解析UI程式碼的資源。

所以一開始我是模仿Winform直接用C#來描述的,不過Winform生成的程式碼很冗長,直接看這種程式碼很費勁,所以考慮優化程式碼結構,看看能否有既可以直接執行生成UI,既可以直觀描述結構的

                             new Panel
{
ToolTip="最大化",
Name="max",
Width = ,
Height = "100%",
Children=
{
new Rectangle
{
Width=,
Height=,
StrokeStyle="",
StrokeFill = "#fff"
}
},
Commands =
{
{
nameof(Button.MouseDown),//可以繫結事件和屬性通知
(s,e)=>
{
(e as MouseButtonEventArgs).Handled = true;
this.WindowState= WindowState.Maximized;
}
}
},
Bindings = //資料繫結
{
{
nameof(Border.Visibility),
nameof(Window.WindowState),
this,
BindingMode.OneWay,//直接使用Lambda表示式作為資料轉換器
a => (WindowState)a == WindowState.Maximized ? Visibility.Collapsed : Visibility.Visible
}
},
Triggers=
{
new Trigger(nameof(Panel.IsMouseOver), Relation.Me)//觸發器可以設定相對位置的其他元素的屬性
{
Setters =
{
{
nameof(Panel.Background),
"#fff"
}
}
}
},
}

這種結構感覺還行吧,微軟的Maui的Mvu模式,感覺和我的很像,而且mvu的最終格式還沒確定。現在maui那邊定義的規則似乎是以方法為主,而我的是以屬性為主,稍微封裝幾個擴充套件方法也可以變成maui那樣的。

另外Mvu模式似乎不提供拖拽的設計器,只提供預覽而已。

CPF的不僅可以預覽,還可以拖拽,設定屬性,生成C#程式碼。支援SVG顯示。

CPF不提供Xaml描述UI,另外CPF提供CSS來描述樣式,類似於Unity3D裡的USS。

為什麼使用CSS來描述?因為CSS結構簡單,簡潔明瞭,方便對多個元素宣告屬性,也方便程式碼複用。比Xaml裡的樣式描述簡潔多了。學習成本低,主要會幾個常用的選擇器就行

* {
FontFamily: 微軟雅黑;
} @keyframes buttonAnimationEnter {
0% {
Background: #1E9FFF;
} 100% {
Background: rgb(75,178,255);
}
} #DropDownPanel TextBlock {
MarginLeft:;
} Button {
Background: #1E9FFF;
Foreground: #fff;
BorderFill: null;
} Button[IsMouseOver=true] {
Background: #1E9FFF;
animation-name: buttonAnimationEnter;
animation-duration: 0.2s;
animation-iteration-count:;
animation-fill-mode: forwards;
} Button[IsPressed=true] {
Background: rgb(30,159,255);
} CheckBox #indeterminateMark {
Fill: #1E9FFF;
} CheckBox #checkBoxBorder {
Background: #fff;
BorderFill: #1E9FFF;
} CheckBox[IsChecked=true] #checkBoxBorder {
Background: #1E9FFF;
BorderFill: #1E9FFF;
} CheckBox Polyline {
StrokeFill: #fff;
}

簡化依賴屬性寫法

        /// <summary>
/// 前景色
/// </summary>
[UIPropertyMetadata(typeof(ViewFill), "Black", UIPropertyOptions.AffectsRender)]
public ViewFill Foreground
{
get { return (ViewFill)GetValue(); }
set { SetValue(value); }
}

簡化附加屬性寫法

        /// <summary>
/// 獲取或設定一個值,該值指示一個子元素在父級 DockPanel 中的位置。 附加屬性
/// </summary>
public static Attached<Dock> Dock
{
get
{
return RegisterAttached(Controls.Dock.Left, (CpfObject obj, string propertyName, object defaultValue, object oldValue, ref object newValue) =>
{
if (obj is UIElement element && element.Parent != null)
{
element.Parent.InvalidateMeasure();
}
});
}
} var dock=DockPanel.Dock(button)//取值
DockPanel.Dock(button,Dock.Left)//設定值

計算屬性

計算屬性來自Vue裡的computed 可繫結,只讀屬性

當SelectValue或者TextSize屬性值變化之後導致TestComputedProperty屬性值變化,有提供屬性通知

        [Computed(nameof(SelectValue), nameof(TextSize))]
public string TestComputedProperty
{
get { return SelectValue == null ? "" : SelectValue.ToString() + TextSize; }
}

CPF已經完成了Windows,Mac和Linux,PC端的跨平臺,移動端的還在計劃中。

CPF、 Avalonia、 Maui一些對比

Avalonia是一個開源的跨平臺的UI框架,用Xaml描述UI的。

CPF Avalonia Maui
最低框架依賴 .net standard2.0/netcore2.0 | net4(支援XP .net standard2.0/netcore2.0 Net6
當前狀態 可用 可用 未釋出,需要明年年底
獨立釋出的程式包大小

較小,依賴少,附帶dll少,Windows端手動裁剪可以到20多M,包含執行時。

如果用net4版,可以更小,不過只能Windows端

稍微大一些,附帶的dll多

估計會比較大,畢竟高版本的框架。

功能也更多。

UI開發模式 C#+CSS Xaml Xaml MVU(C#)
支援平臺 Windows,Mac,Linux,移動端暫時不支援 Windows,Mac,Linux,移動端支援 PC和移動端都支援
一些細節問題 多平臺支援中文輸入法,暫時不支援觸控事件,暫時不支援硬體加速 輸入法支援度不夠,支援觸控事件,支援硬體加速 支援
設計器 預覽和拖拽 預覽 xaml預覽和拖拽,mvu預覽

執行的時候,檢視元素和除錯

一份程式碼,兩個目標框架支援,一部分程式碼通過編譯條件符來區分

我也不敢說我的CPF有多完善,至少常用控制元件基本都有了,寫寫小工具,小應用還是可以的。之後會進一步完善。如果你想使用CPF,必須用VS2019,才能安裝外掛來做設計器預覽,才能釋出Netcore3。

dll免費,可以商業開發。

官網:http://cpf.cskin.net/

以後會陸續釋出一些cpf的教程