CPF C#跨平臺桌面UI框架

系列教程

CPF 入門教程(一)

CPF 門教程 - 資料繫結和命令繫結(二)

CPF 入門教程 - 樣式和動畫(三)

CPF 入門教程 - 繪圖(四)

CPF 入門教程 - 設計器和模板庫的使用(五)

CPF 入門教程 - 控制元件佈局(六)

CPF 入門教程 - 屬性和事件(七)

CPF 入門教程 - 各個控制元件介紹(八)

大部分控制元件和WPF對應的,用法大部分可以參考WPF

注意執行緒安全問題,大部分控制元件的依賴屬性是可以支援執行緒訪問的,但是如果是集合型別的,對集合新增移除這些操作會有執行緒安全問題,必須委託到主執行緒。控制元件的方法不支援執行緒呼叫,必須委託到主執行緒。

對於MainModel 也必須注意,最好不要多執行緒範圍MainModel的屬性,必須委託到主執行緒。

控制元件的Invoke方法或者CPF.Threading.Dispatcher.MainThread.Invoke

Invoke(()=> {
//操作程式碼
});

Border

在另一個元素四周繪製邊框和背景,支援任意圓角和陰影,大部分元素都提供邊框設定

CornerRadius屬性設定四個角的圓角大小

BorderType定義兩種邊框模式

/// 四周邊框一樣粗,BorderStroke屬性定義粗細樣式,支援設定虛線

BorderStroke,

/// 四周邊框可以不同粗細,BorderThickness屬性定義四周粗細,如果定義圓角了可能會有鋸齒

BorderThickness,

ShadowHorizontal ,ShadowVertical,ShadowBlur,ShadowColor  提供對陰影的設定

Button

繼承自ContentControl

Content屬性可以設定字串,圖片或者UIElement等等的內容,一般的如果做圖示加文字效果,直接在設計器里加圖示加文字的控制元件組就行

CheckBox

Content屬性可以設定字串,圖片或者UIElement等等的內容

IsThreeState定義是否是三種狀態。 IsChecked定義選中狀態

 

RadioButton

Content屬性可以設定字串,圖片或者UIElement等等的內容

通過這個GroupName屬性分組,通過Window或者View這類的根元素的GetRadioButtonValue()方法獲取選中值,或者用RadioButtonGroup自動繫結

        [RadioButtonGroup("分組1", true)]//繫結RadioButton分組的值,只能在View裡使用,預設是用RadioButton的Content作為繫結值
public string Group1
{
get { return GetValue<string>(); }
set { SetValue(value); }
}

ComboBox

Items可以繫結陣列或者集合,比如combobox.Items=new String[]{“dfsf”,”gdfs”};

除了直接設定之外也可以直接呼叫Add方法新增,ComboBox.Items.Add(“dfsfs”);

也可以直接新增ListBoxItem物件

資料項可以是簡單的字串,數值,也可以是自定義類,如果是自定義類,需要定義 DisplayMemberPathSelectedValuePath 屬性確定該顯示自定義物件的哪個屬性。

IsVirtualizing虛擬模式,如果用虛擬模式,Item的高度只能是固定的那種,下拉框高度也是固定的,這種模式可以載入大量資料不會卡

IsEditable 啟用編輯模式

SelectionMode 選擇模式,可以設定為多選或者單選

ItemTemplate 設定Item的模板,型別繼承ListBoxItem

ListBox

資料繫結與操作和ComboBox基本一致,

ItemsPanel 定義內部佈局容器,你可以改成水平的或者WrapPanel等等,比如 ItemsPanel=new StackPanel{Orientation=Orientation.Horizontal},虛擬模式下只能用StackPanel

TreeView

Items里加資料外,可以直接加TreeViewItem

DisplayMemberPath定義自定義物件顯示的屬性

ItemsMemberPath 定義自定義物件子節點的屬性名

ItemTemplate 定義模板型別繼承TreeViewItem

DataGrid

暫時不支援自適應列寬度

Columns定義列,列寬支援固定值和權重,權重就是對固定寬度之後的剩餘空間的分配,DataGridComboBoxColumnBindingMode定義繫結模式,雙向繫結和自動重新整理需要資料來源支援集合通知INotifyCollectionChanged和裡面的資料項要實現INotifyPropertyChanged介面

            new DataGrid
{
Width = "60%",
Height = "60%",
Columns ={
new DataGridComboBoxColumn { Header="dfsd", Binding=new DataGridBinding("p1",BindingMode.TwoWay),Width=100,Items={"0","1","2","3" } }, new DataGridCheckBoxColumn { Header="d1fsd", Binding=new DataGridBinding("p2"){ BindingMode= BindingMode.TwoWay },Width=100, }, new DataGridTextColumn { Header="3dfsd", Binding=new DataGridBinding("p3"){ BindingMode= BindingMode.TwoWay },Width="*" }, new DataGridTextColumn { Header="輸入型別驗證", Binding=new DataGridBinding("p4"){ BindingMode= BindingMode.TwoWay },Width="100" }, new DataGridTextColumn { Header="dfsd", Binding=new DataGridBinding("p5"),Width=100 }, },
Bindings = { { nameof(DataGrid.Items), nameof(Model.Data) } }
};

如果要往裡面加按鈕和其他元素,新增 DataGridTemplateColumn 列,自定義單元格模板繼承DataGridCellTemplat模板設定到CellTemplate屬性,

new DataGridTemplateColumn{Hearder=”da”,Width=100,CellTemplate=typeof(XXXX)}

Picture

用來顯示圖片的元素,Source屬性,可以直接設定URL和檔案路徑,也可以設定byte[]和Stream的圖片資料。res://開頭的是讀取內嵌資源,區分大小寫

StretchStretchDirection 縮放填充模式和WPF裡的一樣的。

Popup

用來做提示的窗體,ToolTip,右鍵選單,下拉框等等就是用這個來做的。

PlacementTarget屬性定義彈出的時候位置相對該元素

Placement 屬性Popup 控制元件開啟時的控制元件方向,並指定 Popup 控制元件在與螢幕邊界重疊時的控制元件行為

Margin 用於調整相對位置的偏移

ContextMenu

Items可以直接繫結資料和ListBox那些一致或者加MenuItem,Separator(分割線)

設定給其他控制元件的ContextMenu屬性

ScrollViewer

表示可包含其他可視元素的可滾動區域。元素加到Content,當元素範圍超過ScrollViewer將出現滾動條

HorizontalScrollBarVisibility,VerticalScrollBarVisibility 滾動條可見性控制

VerticalOffset、HorizontalOffset 滾動偏移的獲取或者設定

TabControl

Items里加TabItem

new TabControl
{
Items =
{
new TabItem
{
Content = new Panel
{
Height = "100%",
Width = "100%",
},
Header = "TabItem",
},
},
Height = 104,
Width = 167,
},

TabIitemHeader屬性可以新增UI元素,可以直接在設計器裡新增控制元件組,用來實現圖示加文字或者加關閉按鈕等等的效果

SwitchAction屬性可以定義切換的動畫

                SwitchAction = (oldItem, newItem) =>
{
if (oldItem != null && oldItem.ContentElement != null)
{
oldItem.ContentElement.TransitionValue(nameof(UIElement.MarginLeft), (FloatField)"-100%", TimeSpan.FromSeconds(0.2), new PowerEase(), AnimateMode.EaseOut, () =>
{
oldItem.ContentElement.Visibility = Visibility.Collapsed;
});
}
if (newItem != null && newItem.ContentElement != null)
{
newItem.ContentElement.Visibility = Visibility.Visible;
newItem.ContentElement.MarginLeft = "100%";
newItem.ContentElement.TransitionValue(nameof(UIElement.MarginLeft), (FloatField)"0%", TimeSpan.FromSeconds(0.2), new PowerEase(), AnimateMode.EaseOut);
}
}

TextBlock  Label

最基本的文字顯示元素,Text屬性設定顯示的字元。一般建議直接使用TextBlock ,TextBlock  屬於最基礎的文字控制元件,Label屬於複合控制元件可以修改模板。

TextBlock TextTrimming 可以設定溢位省略號

TextBox

文字輸入控制元件,支援圖文複製貼上顯示。

作為單行文字框需要設定這些屬性,高度調小一些

AcceptsReturn: false;

AcceptsTab :false;

HScrollBarVisibility:Hidden;

VScrollBarVisibility :Hidden;

Padding 可以調整文字到邊框的邊距

Document 屬性用來處理稍微複雜的文件元素,比如實現QQ氣泡

Window

支援任意透明,對於部分Linux上黑底問題,需要Linux開啟桌面合成,預設是不帶窗體框架的(標題欄,系統按鈕,陰影等),如果需要窗體框架,裡面加WindowFrame

ShowDialog()是非同步寫法,ShowDialogSync 是同步寫法

WindowFrame

通用窗體框架,包含窗體邊框,系統按鈕,陰影這些元素。預設的Window是沒有系統按鈕那些元素的,加入這個WindowFrame就有了。除了做頂級的窗體外,你可以用這個做定義的內嵌窗體,自定義內嵌窗體需要實現IWindow介面

MaximizeBox是否顯示最大化還原按鈕

MinimizeBox是否顯示最小化

DockPanel

佈局容器,裡面的子元素設定附加屬性 DockPanel.Dock 定義停靠行為

Grid

網格佈局容器,裡面的子元素設定附加屬性 Grid. RowIndex  Grid. ColumnIndex   Grid. RowSpan(跨越的行的數量,預設值1)   Grid. ColumnSpan(跨越列的數量,預設值1)  定義佈局行為

ColumnDefinitions,RowDefinitions  列和行,寬度和高度支援權重*或者固定的數值

new Grid
{
BorderStroke = "1,Solid",
BorderFill = "#959595",
PresenterFor = this,
Name = "testGrid",
ColumnDefinitions =
{
new ColumnDefinition
{ },
new ColumnDefinition
{ },
},
Children =
{
new GridSplitter
{
Height = "100%",
MarginLeft = 0f,
Attacheds =
{
{
Grid.ColumnIndex,
1
},
},
},
new Border
{
BorderThickness = "1,2,1,1",
BorderType = BorderType.BorderThickness,
MarginLeft = 69,
Height = 37,
Width = 47,
},
},
Height = 147,
Width = 165,
}

MessageBox.Show()

預設彈窗,需要主窗體存在的時候才能使用,樣式繼承主窗體或者設定的Owner

SVG

Source屬性,可以是svg檔案的地址,路徑,可以內嵌或者網路的。也可以直接把SVG的文件字元傳入,比如<svg>…….</svg>的svg文件

支援顯示SVG圖形,暫時不支援裡面的濾鏡,動畫,圖片引用,文字等,只能顯示簡單的圖形,一般作為向量圖示來使用。對於一些無法顯示的svg,可以找svg編輯工具轉換一下

影象縮放方式和Picture控制元件的一樣

Switch

開關按鈕,OnColor,OffColor 定義開和關的顏色

DatePicker,TimePicker

日期和時間控制元件

LayerDialog

定義一個遮罩彈出層對話方塊

new LayerDialog { Width = 400, Height = 300, Content = new Button { Content = "測試" } }.ShowDialog(this);

LoadingBox

定義一個遮罩載入動畫。下面的是擴充套件方法,需要using CPF;

// 定義一個載入動畫,你可以將耗時操作放到work委託裡,可以非同步等待返回一個值。裡面可以執行多個分段的任務,並且重新整理Message。
var r = await this.ShowLoading("開始載入...",a =>
{
System.Threading.Thread.Sleep(1000);
a.Message = "載入元件1...";
System.Threading.Thread.Sleep(1000);
a.Message = "載入元件2...";
System.Threading.Thread.Sleep(1000);
return "結果";
});

Chart

支援折線,曲線,條形的顯示,支援縮放滾動

new Chart
{
GridShowMode = GridShowMode.Horizontal,
GridFill = "#A5A5A5",
YAxisScaleCount = 3,
ChartFill = "#C7E5F6",
CanScroll = true,
IsAntiAlias = true,
Height = 184,
Width = 245,
XAxis=
{
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
},
Data =
{
new ChartBarData
{
Name="test",
Fill="#faf",
Format="#'%'",
Data =
{
1,
2,
3
}
},
new ChartBarData
{
Name="test1",
Fill="#0af",
Format="#'%'",
ShowValueTip=true,
Data =
{
4,
5,
2
}
},
new ChartLineData
{
Name="test2",
LineFill="#a0f",
Format="#'%'",
LineType= LineTypes.Curve,
BottomFill="#ff000033",//ShowValueTip=true,
Data =
{
4,
5,
2,
3,
4,
3,
4,
5,
2,
3,
4,
3,
}
},
new ChartLineData
{
Name="test2測試",
LineFill="#0a0",
BottomFill="#00000055",
Data =
{
3,
4,
5,
4,
3,
5,
3,
4,
5,
4,
3,
5,
5,
3,
4,
5,
4,
6,
5
}
},
}
},

PieChart

支援餅圖,圓環圖

new PieChart
{
RingWidth = "40%",
Height = 219,
Width = 279,
IsAntiAlias=true,
Data =
{
new PieChartData
{
Name="test1",
Fill="#ff000055",
Value=3
},
new PieChartData
{
Name="test2",
Fill="#00ff0055",
Value=5
},
new PieChartData
{
Name="test3",
Fill="#0000ff55",
Value=5
},
new PieChartData
{
Name="test4",
Fill="#00ffff55",
Value=5
},
new PieChartData
{
Name="test5",
Fill="#a0fa0f55",
Value=1
},
}
},

NotifyIcon

系統托盤圖示或者狀態列圖示,不是所有系統都支援,部分Linux上不支援顯示。

一般定義個全域性的NotifyIcon物件就行,不需要新增到窗體上

NumericUpDown

用於設定數值的控制元件,Maximum,Minimum,Value   最大值,最小值,當前值

Slider

Expander

可摺疊內容顯示視窗的標題

new Expander
{
Header="test",
Content= new Button
{
Content="test內容"
}
}

想修改控制元件元素和效果?繼承你要修改的控制元件,然後重寫InitializeComponent 把定義程式碼寫在裡面,不知道怎麼定義?設計器,右鍵模板庫,基礎控制元件模板,選擇後自動新增,自己根據需要修改。模板中使用PresenterFor 屬性是為了區分該物件是否是該模板物件內部使用的。單純的用name來區分的話會出現錯誤,因為name會有重複,尤其是多種複雜物件巢狀的時候。