CPF 入门教程
CPF netcore跨平臺UI框架
系列教程
CPF 入門教程(一)
CPF 入門教程 - 數據綁定和命令綁定(二)
CPF 入門教程 - 樣式和動畫(三)
CPF 入門教程 - 繪圖(四)
數據綁定和Wpf類似,支持雙向綁定。數據綁定和命令綁定是UI和業務邏輯分離的基礎。
首先,你需要定義個MainModel,為了可以有屬性通知,這個類可以繼承CpfObject或者自己實現INotifyPropertyChanged
1 public class MainModel : CpfObject
2 {
3 [PropertyMetadata("默認值")]
4 public string Test
5 {
6 get { return (string)GetValue(); }
7 set { SetValue(value); }
8 }
9 }
這里定義了一個Test屬性,并且設置默認值為“默認值”
設計個測試界面,加個TextBlock和Button,同時TextBlock設置綁定,綁定定義在Bindings屬性,{nameof(TextBlock.Text),nameof(MainModel.Test) } 表示TextBlock的Text綁定到DataContext的Test屬性
public class Window4 : Window
{
protected override void InitializeComponent()
{
Title = "標題";
Width = 344.8f;
Height = 126.4f;
Background = null;
Children.Add(new WindowFrame(this, new Panel
{
Width = "100%",
Height = "100%",
Children =
{
//內容元素放這里
new Button
{
MarginLeft = 223.8f,
MarginTop = 25.7f,
Height = 28f,
Width = 67.4f,
Content = "Button",
},
new TextBlock
{
MarginLeft = 36.7f,
MarginTop = 31.6f,
Text = "TextBlock",
Bindings =
{
{nameof(TextBlock.Text),nameof(MainModel.Test) }
}
},
}
}));
LoadStyleFile("res://ConsoleApp1.Stylesheet1.css");
//加載樣式文件,文件需要設置為內嵌資源
}
}
修改program,設置Window的DataContext和CommandContext
var model = new MainModel();
Application.Run(new Window4 { DataContext = model, CommandContext = model });
寫好之后,運行看看效果。TextBlock那邊顯示MainModel那邊定義的默認值
接下來定義命令,通過按鈕點擊修改Test值,同時自動更新到TextBlock
MainModel里增加個Click方法
class MainModel : CpfObject
{
[PropertyMetadata("默認值")]
public string Test
{
get
{
return (string)GetValue();
}
set
{
SetValue(value);
}
}
public void Click()
{
Test += "test";
}
}
Button那邊增加命令綁定,Commands里添加,{nameof(Button.Click),nameof(MainModel.Click) } 表示Button的Click事件綁定到CommandContext的Click方法
new Button
{
MarginLeft = 223.8f,
MarginTop = 25.7f,
Height = 28f,
Width = 67.4f,
Content = "Button",
Commands =
{
{nameof(Button.Click),nameof(MainModel.Click) }
}
},
運行效果,點擊一次增加一次test。這就是最簡單的模型視圖分離的數據綁定
接下來綁定集合
設計界面,添加Button和ListBox
往MainModel里加上Items集合屬性,構造函數里初始化集合,用Collection 是為了有集合變化通知,也可以使用ObservableCollection。(string, string) 就是元組里簡化的結構體類型定義,是一種偷懶簡化數據定義的方式,不過這種方式的話,改item就不能更新到UI了,需要可以更新到UI的就需要自定義類型,繼承CpfObject或者繼承INotifyPropertyChanged的類型作為Item
public MainModel()
{
Items = new Collection<(string, string)>();
}
public Collection<(string,string)> Items
{
get
{
return (Collection<(string, string)>)GetValue();
}
set
{
SetValue(value);
}
}
MainModel里加個AddItem方法
public void AddItem()
{
Items.Add(("test" + Items.Count, Items.Count.ToString()));
}
最終代碼
using CPF;
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApp1
{
class MainModel : CpfObject
{
[PropertyMetadata("默認值")]
public string Test
{
get
{
return (string)GetValue();
}
set
{
SetValue(value);
}
}
public void Click()
{
Test += "test";
}
public MainModel()
{
Items = new Collection<(string, string)>();
}
public Collection<(string, string)> Items
{
get
{
return (Collection<(string, string)>)GetValue();
}
set
{
SetValue(value);
}
}
public void AddItem()
{
Items.Add(("test" + Items.Count, Items.Count.ToString()));
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CPF;
using CPF.Drawing;
using CPF.Controls;
using CPF.Shapes;
using CPF.Styling;
using CPF.Animation;
namespace ConsoleApp1
{
public class Window4 : Window
{
protected override void InitializeComponent()
{
Title = "標題";
Width = 338.4f;
Height = 205.6f;
Background = null;
Children.Add(new WindowFrame(this, new Panel
{
Width = "100%",
Height = "100%",
Children =
{
//內容元素放這里
new Button
{
MarginLeft = 223.8f,
MarginTop = 25.7f,
Height = 28f,
Width = 67.4f,
Content = "Button",
Commands =
{
{
nameof(Button.Click),
nameof(MainModel.Click)
}
}
},
new TextBlock
{
MarginLeft = 36.7f,
MarginTop = 31.6f,
Text = "TextBlock",
Bindings =
{
{
nameof(TextBlock.Text),
nameof(MainModel.Test)
}
}
},
new Button
{
MarginLeft = 223.8f,
MarginTop = 91.6f,
Height = 28f,
Width = 67.4f,
Content = "添加Item",
Commands =
{
{nameof(Button.Click),nameof(MainModel.AddItem) }
}
},
new ListBox
{
SelectedValuePath = "Item2",//綁定Item里的Item1屬性
DisplayMemberPath = "Item1",//綁定Item里的Item2屬性
BorderStroke = "1,Solid",
BorderFill = "#DEDEDE",
MarginLeft = 36.7f,
MarginTop = 60.8f,
Height = 76.5f,
Width = 123.2f,
Bindings =
{
{nameof(ListBox.Items),nameof(MainModel.Items) }
}
},
}
}));
LoadStyleFile("res://ConsoleApp1.Stylesheet1.css");
//加載樣式文件,文件需要設置為內嵌資源
}
}
}
最終運行效果,點擊添加Item的按鈕,ListBox里會增加Item
數據類型轉換,Test屬性值后面加1。 數據轉換器用方法或者Lambda就行。
{
nameof(TextBlock.Text),
nameof(MainModel.Test),
null,
BindingMode.OneWay,
(string a)=>a+"1"
}
UI元素之間綁定,TextBox的Text綁定到Button的Content,其中TextBox設置PresenterFor=this,是為了標記TextBox的作用域在當前類,因為Name是可以重復的,元素嵌套如果有相同Name會無法判斷元素是在哪里的,所以用PresenterFor加標記判斷,而且這樣可以通過FindPresenterByName方法來獲取當前類里的標記元素來綁定
protected override void InitializeComponent()
{
Title = "標題";
Width = 338.4f;
Height = 205.6f;
Background = null;
Children.Add(new WindowFrame(this, new Panel
{
Width = "100%",
Height = "100%",
Children =
{
//內容元素放這里
new Button
{
MarginLeft = 223.8f,
MarginTop = 25.7f,
Height = 28f,
Width = 67.4f,
Content = "Button",
Commands =
{
{
nameof(Button.Click),
nameof(MainModel.Click)
}
},
Bindings =
{
{
nameof(Button.Content),
nameof(TextBox.Text),
FindPresenterByName("textBox")
}
}
},
new TextBlock
{
MarginLeft = 36.7f,
MarginTop = 31.6f,
Text = "TextBlock",
Bindings =
{
{
nameof(TextBlock.Text),
nameof(MainModel.Test),
null,
BindingMode.OneWay,
(string a)=>a+"1"
}
}
},
new Button
{
MarginLeft = 223.8f,
MarginTop = 91.6f,
Height = 28f,
Width = 67.4f,
Content = "添加Item",
Commands =
{
{
nameof(Button.Click),
nameof(MainModel.AddItem)
}
}
},
new ListBox
{
SelectedValuePath = "Item2",
//綁定Item里的Item1屬性
DisplayMemberPath = "Item1",
//綁定Item里的Item2屬性
BorderStroke = "1,Solid",
BorderFill = "#DEDEDE",
MarginLeft = 36.7f,
MarginTop = 60.8f,
Height = 76.5f,
Width = 123.2f,
Bindings =
{
{
nameof(ListBox.Items),
nameof(MainModel.Items)
}
}
},
new TextBox
{
Name="textBox",
PresenterFor=this,
AcceptsReturn= false,
HScrollBarVisibility= ScrollBarVisibility.Hidden,
VScrollBarVisibility= ScrollBarVisibility.Hidden,
MarginLeft = 144.8f,
MarginTop = 28.1f,
Width = 74.5f
},
}
}));
LoadStyleFile("res://ConsoleApp1.Stylesheet1.css");
//加載樣式文件,文件需要設置為內嵌資源
}
TextBox輸入,會自動更新Button的文字
命令綁定除了事件之外,屬性變化也可以綁定為命令,比如,鼠標移入和移出就調用
Commands =
{
{
nameof(Button.IsMouseOver),
nameof(MainModel.Click)
}
}
主要綁定就這些,如果要雙向綁定,命令參數等等,看VS那邊的智能提示
總結
- 上一篇: 黑芝麻怎么看炒熟了
- 下一篇: kali安装及配置ssr客户端