Wtf(暂时命名, 随便起的 = _=), 模仿 WPF 的框架, 还没有完善, 只有简单的基础元素, 支持数据绑定. 虽然支持 mono 但是 mono 有 bug
写这个只是兴趣爱好, 感觉也没多大意义了, 如果这个 UI 框架完善了, 有多少人愿意用? 毕竟 Windows 上有 WPF, 而且 C# 跨平台需求也不多啊. 我对 WPF 也不算熟悉, 要完善的话, 还有很多要写. 一大堆常用控件和设计器. 不过我不用 XML 来描述, 而是直接用 C# 来定义, 设计器直接生成 C# 代码, 因为我觉得, 如果有强大的设计器, 写 XML 就是多余的, 而且解析 XML 还影响性能, 对于 WPF, 我觉得 Xaml 太啰嗦了.
WtfObject 相当于 WPF 里的 DependencyObject 依赖对象. 继承该类的对象, 所有属性默认都是依赖属性
属性写法:
- /// <summary>
- /// 绑定的数据上下文
- /// </summary>
- [UIPropertyMetadata(null, true)]
- public virtual object DataContext
- {
- get { return GetValue<object>(); }
- set { SetValue(value); }
- }
属性上的特性可以是 PropertyMetadata 或者 UIPropertyMetadata 中的一个, 默认值可以通过这两个特性来设置. 如果不加这两个特性, 那默认值就是 null 或者 0
如果是复杂属性类型默认值, 可以通过重写 OnOverrideMetadata 来设置
- protected override void OnOverrideMetadata(OverrideMetadata overridePropertys)
- {
- base.OnOverrideMetadata(overridePropertys);
- overridePropertys.Override("StrokeStyle", new UIPropertyMetadataAttribute(new Stroke(1), false, false, true));
- }
数据绑定:
- var bind = 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["Text"] <= button["Test"];// 右到左数据绑定
- var bind = label["Text"]>= button["Test"];// 左到右数据绑定
- var bind = label["Text"] != button["Test"];// 右到左数据绑定, 只传递一次
- var bind = label["Text"] == button["Test"];// 双向绑定
命令绑定:
当事件触发或者属性变化的时候调用方法
- label.AddCommand("MouseDown","button1_Click","CommandContext", Wtf.Windows.CommandParameter.EventArgs);
- /// <summary>
- /// 添加处理命令, 命令方法在 CommandContext 或者其他属性的对象上
- /// </summary>
- /// <param name="eventName"> 触发的事件名或者属性名 </param>
- /// <param name="methodName"> 命令方法名 </param>
- /// <param name="propertyName"> 命令对象所在的属性名 </param>
- /// <param name="ps"> 方法参数, 可以是自定义的数据或者相关属性或者事件的数据 </param>
- public void AddCommand(string eventName, string methodName, string propertyName = "CommandContext", params object[] ps)
一些类型的隐式转换
Brush, Color : "#0000ff" "#ff0000ff" "255,255,255" "255,255,255,255" 颜色字符串转换, 按顺序是 r,g,b,a,r,g,b
FloatValue: "10%" "100" "zero" "auto" 100 100.5 数字或者百分比字符串转换, 整形, 浮点数据自动转换
触发器样式例子
按钮的鼠标操作效果, 鼠标移入移出按下背景色变化
- Styling.Trigger hover = new Styling.Trigger { Condition = Styling.Conditions.Equals, Property = "IsMouseOver", Value = true };
- hover.Setters.Add("Background", Drawing.Brush.Parse("#ff0000"));
- Styling.Trigger normal = new Styling.Trigger { };
- normal.Setters.Add("Background", Drawing.Brush.Parse("#00ff00"));
- Styling.Trigger press = new Styling.Trigger { Condition = Styling.Conditions.Equals, Property = "IsMouseCaptured", Value = true };
- press.Setters.Add("Background", Drawing.Brush.Parse("#ffff00"));
- label.Triggers.Add(normal);
- label.Triggers.Add(hover);
- label.Triggers.Add(press);
- label.MouseDown += delegate
- {
- label.CaptureMouse();
- };
- label.MouseUp += delegate
- {
- label.ReleaseMouseCapture();
- };
WtfObject 的属性设置的值优先级比触发器样式设置的值要高, 所以当你设置了属性值, 触发器样式可能没有效果
添加 UI 元素, UI 元素可以互相嵌套
- var root = testControl1.RootUIElement;
- root.Foreground = "#ff0000";
- root.FontFamily = "微软雅黑";
- root.FontSize = 16;
- root.Children.Add(label);
- root.Children.Add(new Windows.Shapes.Ellipse
- {
- Stroke = "#0000ff",
- Fill = "white",
- Width = 40,
- Height = 20,
- MarginLeft = 30,
- MarginTop = 30
- });
- root.Children.Add(new Windows.Shapes.Ellipse
- {
- Stroke = "#0000ff",
- Fill = "white",
- Width = 40,
- Height = 20,
- MarginRight = "30%",
- MarginTop = 30
- });
元素布局, 支持百分比布局, margin 调整定位, 默认居中.
触发器绑定动画
- var t = new Trigger();
- Storyboard ss = new Storyboard();
- ss.Duration = new TimeSpan(0, 0, 0, 0, 500);
- var tl = new Timeline(1);
- tl.KeyFrames.Add(new KeyFrame<FloatValue> { Property = "Height", Value = 300, Ease = new BounceEase(), AnimateMode = AnimateMode.EaseIn });
- tl.KeyFrames.Add(new KeyFrame<FloatValue> { Property = "Width", Value = "30%", Ease = new BounceEase(), AnimateMode = AnimateMode.EaseIn });
- tl.KeyFrames.Add(new KeyFrame<GeneralTransform> { Property = "RenderTransform", AnimateMode = AnimateMode.EaseOut, Value = new GeneralTransform { Angle = 30 }, Ease = new ElasticEase() });
- //tl.KeyFrames.Add(new KeyFrame<SolidColorBrush> { Property = Shape.FillProperty, Value = "White" });
- ss.Timelines.Add(tl);
- t.Property = "IsMouseOver";
- t.Value = true;
- t.Animation = ss;
- t.Setters.Add("Fill", Brush.Parse("#fff"));
- v.Triggers.Add(t);
如果写自定义控件, 继承 Wtf.Windows.Controls.Control 然后重写 InitializeComponent 把样式定义代码写在里面, 如果再次继承修改的话, 可以重写覆盖.
dll 暂时不提供下载
来源: https://www.cnblogs.com/dskin/p/9514881.html