zoukankan      html  css  js  c++  java
  • 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那边的智能提示

  • 相关阅读:
    Go简介
    sRGB标准与伽马校正
    【Web】HTTP基本认证之 Basic Auth
    【ElasticSearch】 ElasticSearch SQL(十三)
    【ElasticSearch】 ElasticSearch X-Pack之用户认证(十二)
    【ElasticSearch】 ElasticSearch Java客户端(十一)
    【ElasticSearch】 ElasticSearch集群分布式文档(十)
    【ElasticSearch】 ElasticSearch集群之分片、副本、故障转移(九)
    【ElasticSearch】 ElasticSearch集群安装(八)
    【ElasticSearch】 全文搜索(七)
  • 原文地址:https://www.cnblogs.com/dskin/p/13493342.html
Copyright © 2011-2022 走看看