CPF 入門教程 – 各個控件介紹(八)

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內容"
    }
}

VideoView

視頻播放控件,Nuget 安裝Xhm.CPF.Vcl      然後使用VideoView控件,控件初始化之後使用MediaPlayer屬性來對播放器進行詳細控制。VideoView. LibVLC一些對象構造需要

 

Vlc封裝參考 //github.com/videolan/libvlcsharp

 

Windows

Nuget 安裝 VideoLAN.LibVLC.Windows

Mac

Nuget 安裝 VideoLAN.LibVLC.Mac

 

Linux上需要安裝

For ubuntu:

apt-get install libvlc-dev

apt-get install vlc

 

WebBrowser

封裝cef的瀏覽器控件

需要安裝Nuget包

<PackageReference Include=”Xhm.CPF.Cef” Version=”0.9″ />

 

到 //cef-builds.spotifycdn.com/index.html#windows64:88.1.6%2Bg4fe33a1%2Bchromium-88.0.4324.96 下載對應平台的二進制文件,一般是選擇 Sample Application ……client.tar.bz2

注意版本號:88.1.6+g4fe33a1+chromium-88.0.4324.96

需要注意的是如果你需要的是Linux平台的,建議自己調整編譯參數重新編譯,因為網站上下載的二進制文件巨大,達到一個G了
一般情況下,把壓縮包里的比如libcef…同目錄里的所有文件和文件夾都複製到你的程序目錄就行
如果是Mac的話
將文件\Release\Chromium Embedded Framework.framework\Chromium Embedded Framework複製到你的程序目錄並重命名為libcef.dylib
將「\Release\Chromium Embedded Framework.framework\Libraries」文件夾中的所有文件和文件夾複製你的程序目錄
將「\Release\Chromium Embedded Framework.framework\Resources」文件夾中的所有文件和文件夾複製到你的程序目錄

如果你需要支持視頻播放,那你需要自己修改編譯參數,重新編譯才行,具體教程可以百度

如果你想自定義特殊功能,比如攔截請求,你需要繼承 WebBrowser,並重寫 OnCreateWebBrowser
OnCreateWebBrowser裏面寫client.LoadHandler = new CpfCefLoadHandler();繼承並重寫對應的Handler並設置過來

mac上運行在任務欄上可能會有多個圖標閃爍之後就沒了,是正常的,cef的多進程問題,不影響使用

 

 

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