前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >造轮子了!NETCore跨平台UI框架,CPF

造轮子了!NETCore跨平台UI框架,CPF

作者头像
梁规晓
发布2019-11-07 11:07:11
1.6K0
发布2019-11-07 11:07:11
举报
文章被收录于专栏:DotNet程序园DotNet程序园

CPF(暂时命名)(Cross platform framework),模仿WPF的框架,支持NETCore的跨平台UI框架,暂时不够完善,只用于测试,暂时只支持Windows和Mac。支持数据绑定,CSS,动画。。。

可能有人会说,不是有个开源的Avalonia ,我试过,不过他的性能不行,启动速度慢,内存占用高,附带的dll一大堆,他的是Xaml来描述UI的,我的不提供Xaml,直接用C#来写,以后将出设计器直接生成C#代码。

CpfObject相当于WPF里的DependencyObject依赖对象。继承该类的对象,所有属性默认都是依赖属性

属性写法:

代码语言:javascript
复制
1         /// <summary>
2         /// 绑定的数据上下文
3         /// </summary>
4         [PropertyMetadata(null)]
5         public object DataContext
6         {
7             get { return GetValue<object>(); }
8             set { SetValue(value); }
9         }

属性上的特性可以是 PropertyMetadata或者UIPropertyMetadata 中的一个,默认值建议通过这两个特性来设置。如果不加这两个特性,那默认值就是null或者0

如果是复杂属性类型默认值,可以通过重写 OnOverrideMetadata 来设置

代码语言:javascript
复制
        protected override void OnOverrideMetadata(OverrideMetadata overridePropertys)
        {
            base.OnOverrideMetadata(overridePropertys);
            overridePropertys.Override("StrokeStyle", new UIPropertyMetadataAttribute(new Stroke(1)));
        }

附加属性:

代码语言:javascript
复制
        /// <summary>
        /// 获取或设置元素行索引
        /// </summary>
        public static Attached<int> RowIndex
        {
            get { return RegisterAttached(0); }
        }

Grid.RowIndex(control, 1);//使用附加属性方式设置行索引
var index = Grid.RowIndex(control);//获取附加属性值

数据绑定:

代码语言:javascript
复制
var bind = label[nameof(Label.Text)] <= "Test";//右到左数据绑定,数据源是DataContext的属性
var bind = label["Text"] >= "Test";//左到右数据绑定,数据源是DataContext的属性
var bind = label["Text"] != "Test";//左到右数据绑定,只传递一次 ,数据源是DataContext的属性
var bind = label["Text"] == "Test";//双向绑定,数据源是DataContext的属性,双向绑定需要对象实现INotifyPropertyChanged


var bind = label[nameof(Label.Text)] <= button["Test"];//右到左数据绑定
var bind = label[nameof(Label.Text)] >= button["Test"];//左到右数据绑定
var bind = label[nameof(Label.Text)] != button["Test"];//左到右数据绑定,只传递一次
var bind = label[nameof(Label.Text)] == button["Test"];//双向绑定

btn.Bindings.Add(nameof(Button.Content), nameof(TextBlock.Text), null, BindingMode.OneWay, a => a.ToString());//通过Bindings属性添加绑定,建议用nameof()这样不容易写错

 

命令绑定:

当事件触发或者属性变化的时候调用方法

代码语言:javascript
复制
Label.Commands.Add(nameof(Window.MouseDown), nameof(Window.DragMove), Relation.Me.Parent);
new Button
    {
       Width = 20,
        Height = 20,
        MarginRight = 30,
        MarginTop = 5,
        Content = "Test",
        Commands = { { nameof(Button.MouseUp), ()=> { window.WindowState = WindowState.Minimized; } } }
     }

 

布局系统

布局流程和WPF差不多,先Measure再Arrange,如果自定义布局容器,可以参考WPF的代码

元素布局,支持百分比布局,margin调整定位,默认居中。相当于CSS里中的绝对定义position: absolute;

MarginLeft,MarginTop,MarginRight,MarginBottom,一般默认值是Auto,当设置值之后固定对应边到父容器到内边距的距离

Width,Height,一般默认值也是Auto,如果没设置,实际尺寸由内容或者子元素尺寸决定,或者由Margin决定

代码语言:javascript
复制
new Border { Width = "100%", Height = "100%", Background = "#fff", }

属性值的自动转换:

代码语言:javascript
复制
Width = "100%";
Width = "Auto";
Width = 100;
Background = Color.FromRgb(100,100,100);
Background = "#fff";
Background =image;

CSS样式

支持简单的选择器

代码语言:javascript
复制
TextBlock { Foreground:rgb(255,0,0);} 选择所有TextBlock类型的元素
.test{Foreground:rgb(255,0,0);} 选择所有包含test 类名的元素,类名通过Classes属性添加
#test{Foreground:rgb(255,0,0);} 选择所有Name属性为test的元素
[IsMouseOver=true]{…}   添加触发器
Button TextBlock{…}   Button里的后代为TextBox的元素,只支持两层
Button>TextBlock{…}   Button直接子元素为TextBox的元素,只支持两层

触发器和动画

代码语言:javascript
复制
.test[IsMouseOver=true]{animation-name:myfirst;animation-duration:1s;animation-iteration-count: 1;}
@keyframes myfirst
{
0%   {Background: #f00;}
25%  {Background: #0ff;}
50%  {Background: #00f;}
100% {Background: #0f0;}
}

通过根元素的LoadStyle方法加载样式,比如Window对象

控件模板:

继承你要修改的控件,然后重写InitializeComponent 把定义代码写在里面,不知道怎么定义?查看内置模板代码,详细模板代码看压缩包里的文档,复制过去,自己根据需要修改

对Mac开发不熟悉,Mac系统下还不能输入中文,有没有猛男赐教一下,怎么调用输入法,打开关闭输入法和控制输入法候选词位置

我感觉模板设计的不够好,还有数据绑定还可以优化一下。各位有什么想法和意见说说。

CPF 下载

DSkin强大、自定义的.NET皮肤界面库,让软件开发更迅速、美观、炫丽。还提供Html快速构建UI的开发模式,入门简单,功能强大

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DotNet程序园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档