CPF 入門教程 - 數據綁定和命令綁定(二)

CPF netcore跨平臺UI框架css

 

系列教程html

CPF 入門教程(一)框架

CPF 入門教程 - 數據綁定和命令綁定(二)ide

 

數據綁定和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屬性,而且設置默認值爲「默認值」this

設計個測試界面,加個TextBlock和Button,同時TextBlock設置綁定,綁定定義在Bindings屬性, {nameof(TextBlock.Text),nameof(MainModel.Test) } 表示TextBlock的Text綁定到DataContext的Test屬性spa

    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那邊的智能提示

相關文章
相關標籤/搜索