diff --git a/CPF.Toolkit.Demo/CPF.Toolkit.Demo.csproj b/CPF.Toolkit.Demo/CPF.Toolkit.Demo.csproj
new file mode 100644
index 0000000..8602593
--- /dev/null
+++ b/CPF.Toolkit.Demo/CPF.Toolkit.Demo.csproj
@@ -0,0 +1,33 @@
+
+
+
+ WinExe
+ netcoreapp3.0
+
+
+
+
+
+ true
+
+ AnyCPU
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CPF.Toolkit.Demo/MainView.cs b/CPF.Toolkit.Demo/MainView.cs
new file mode 100644
index 0000000..e186886
--- /dev/null
+++ b/CPF.Toolkit.Demo/MainView.cs
@@ -0,0 +1,44 @@
+using CPF;
+using CPF.Animation;
+using CPF.Charts;
+using CPF.Controls;
+using CPF.Drawing;
+using CPF.Shapes;
+using CPF.Styling;
+using CPF.Svg;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace CPF.Toolkit.Demo
+{
+ public class MainView : Window
+ {
+ protected override void InitializeComponent()
+ {
+ //LoadStyleFile("res://CPF.Toolkit.Demo/Stylesheet1.css");
+
+ this.Title = "标题";
+ this.Width = 500;
+ this.Height = 400;
+ this.Background = null;
+ var vm = new MainViewModel();
+ this.DataContext = this.CommandContext = vm;
+ this.Children.Add(new WindowFrame(this, new Panel
+ {
+ Width = "100%",
+ Height = "100%",
+ Children =
+ {
+ new Button
+ {
+ Content="按钮",
+ [nameof(Button.Click)] = new CommandDescribe((ss,ee) => vm.Test()),
+ }
+ },
+ }));
+ this.Behaviors.Add(new ViewBehavior());
+ }
+ }
+}
diff --git a/CPF.Toolkit.Demo/MainViewModel.cs b/CPF.Toolkit.Demo/MainViewModel.cs
new file mode 100644
index 0000000..8fc4d55
--- /dev/null
+++ b/CPF.Toolkit.Demo/MainViewModel.cs
@@ -0,0 +1,27 @@
+using CPF.Controls;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CPF.Toolkit.Demo
+{
+ internal class MainViewModel : ViewModelBase
+ {
+ protected override void OnLoaded()
+ {
+
+ }
+
+
+ public void Test()
+ {
+ this.Dialog.Alert("确定删除所选的文件吗?", "确定删除", DialogType.Warn, "", "取消", "删除");
+ }
+
+ //protected override void OnClosing(ClosingEventArgs e)
+ //{
+ // e.Cancel = true;
+ // base.OnClosing(e);
+ //}
+ }
+}
diff --git a/CPF.Toolkit.Demo/Program.cs b/CPF.Toolkit.Demo/Program.cs
new file mode 100644
index 0000000..789546d
--- /dev/null
+++ b/CPF.Toolkit.Demo/Program.cs
@@ -0,0 +1,21 @@
+using CPF.Platform;
+using CPF.Skia;
+using CPF.Windows;
+using System;
+
+namespace CPF.Toolkit.Demo
+{
+ internal class Program
+ {
+ [STAThread]
+ static void Main(string[] args)
+ {
+ Application.Initialize(
+ (OperatingSystemType.Windows, new WindowsPlatform(), new SkiaDrawingFactory())
+ , (OperatingSystemType.OSX, new CPF.Mac.MacPlatform(), new SkiaDrawingFactory())//如果需要支持Mac才需要
+ , (OperatingSystemType.Linux, new CPF.Linux.LinuxPlatform(), new SkiaDrawingFactory())//如果需要支持Linux才需要
+ );
+ Application.Run(new MainView());
+ }
+ }
+}
diff --git a/CPF.Toolkit.Demo/Stylesheet1.css b/CPF.Toolkit.Demo/Stylesheet1.css
new file mode 100644
index 0000000..d895ab6
--- /dev/null
+++ b/CPF.Toolkit.Demo/Stylesheet1.css
@@ -0,0 +1,502 @@
+/*@font-face {
+ font-family: '微软雅黑';
+ src: url('res://ConsoleApp1/msyh.ttc');
+}*/ /*加载字体*/
+
+/** {
+ FontFamily: 微软雅黑;
+}*/
+
+@media windows {
+ * {
+ FontFamily: '微软雅黑'; /*不同系统的字体不同,自己根据情况改或者使用内嵌字体*/
+ }
+}
+
+@media osx {
+ * {
+ FontFamily: '苹方-简';
+ }
+}
+
+@media linux {
+ * {
+ FontFamily: '文泉驿正黑';
+ }
+}
+/*设置窗体标题栏背景颜色圆角*/
+/*#caption {
+ IsAntiAlias: true;
+ Background: #2c2c2c;
+ CornerRadius:5,5,0,0;
+ Height:30;
+}
+#frame {
+ CornerRadius: 5;
+ IsAntiAlias: true;
+}*/
+Button {
+ BorderFill: #DCDFE6;
+ IsAntiAlias: True;
+ CornerRadius: 4,4,4,4;
+ Background: #FFFFFF;
+}
+
+ Button[IsMouseOver=true] {
+ BorderFill: rgb(198,226,255);
+ Background: rgb(236,245,255);
+ Foreground: rgb(64,158,255);
+ }
+
+ Button[IsPressed=true] {
+ BorderFill: rgb(58,142,230);
+ }
+
+ Button.primary {
+ BorderFill: rgb(64,158,255);
+ CornerRadius: 4,4,4,4;
+ Background: rgb(64,158,255);
+ Foreground: #FFFFFF;
+ }
+
+ Button.primary[IsMouseOver=true] {
+ BorderFill: rgb(102,177,255);
+ Background: rgb(102,177,255);
+ Foreground: #FFFFFF;
+ }
+
+ Button.primary[IsPressed=true] {
+ BorderFill: rgb(58,142,230);
+ Background: rgb(58,142,230);
+ }
+
+ Button.success {
+ BorderFill: rgb(103,194,58);
+ CornerRadius: 4,4,4,4;
+ Background: rgb(103,194,58);
+ Foreground: #FFFFFF;
+ }
+
+ Button.success[IsMouseOver=true] {
+ BorderFill: rgb(133,206,97);
+ Background: rgb(133,206,97);
+ Foreground: #FFFFFF;
+ }
+
+ Button.success[IsPressed=true] {
+ BorderFill: rgb(93,175,52);
+ Background: rgb(93,175,52);
+ }
+
+ Button.danger {
+ BorderFill: rgb(245,108,108);
+ Background: rgb(245,108,108);
+ CornerRadius: 4,4,4,4;
+ Foreground: #FFFFFF;
+ }
+
+ Button.danger[IsMouseOver=true] {
+ BorderFill: rgb(247,137,137);
+ Background: rgb(247,137,137);
+ Foreground: #FFFFFF;
+ }
+
+ Button.danger[IsPressed=true] {
+ BorderFill: rgb(221,97,97);
+ Background: rgb(221,97,97);
+ }
+
+#dialogClose {
+ BorderFill: null;
+}
+
+TextBox, .textBox, DatePicker {
+ Background: #fff;
+ IsAntiAlias: true;
+ BorderFill: #DCDFE6;
+ CornerRadius: 4,4,4,4;
+ BorderStroke: 1;
+}
+
+ .groupPanel TextBox, DatePicker TextBox, .textBox TextBox {
+ BorderStroke: 0;
+ }
+
+ .textBox[IsKeyboardFocusWithin=true] {
+ BorderFill: #1E9FFF;
+ }
+
+.singleLine { /*单行文本框*/
+ AcceptsReturn: false;
+ HScrollBarVisibility: Hidden;
+ VScrollBarVisibility: Hidden;
+}
+
+ .singleLine #contentPresenter {
+ Padding: 3;
+ }
+
+.multiline { /*多行文本框*/
+}
+
+
+.slotLeft {
+ CornerRadius: 0,4,4,0;
+ BorderFill: #DCDFE6;
+ Background: #F5F7FA;
+ BorderThickness: 1,0,0,0;
+ BorderType: BorderThickness;
+ MarginTop: 0;
+ MarginBottom: 0;
+ MarginRight: 0;
+}
+
+RadioButton #radioButtonBorder {
+ StrokeFill: rgb(220,223,230);
+}
+
+RadioButton[IsChecked=true] #radioButtonBorder {
+ StrokeFill: #1E9FFF;
+ Fill: #1E9FFF;
+}
+
+RadioButton #optionMark {
+ StrokeFill: #1E9FFF;
+ Fill: #fff;
+}
+
+CheckBox #indeterminateMark {
+ Fill: #1E9FFF;
+}
+
+CheckBox #checkBoxBorder {
+ Background: #fff;
+ BorderFill: rgb(220,223,230);
+}
+
+CheckBox[IsChecked=true] #checkBoxBorder {
+ Background: #1E9FFF;
+ BorderFill: #1E9FFF;
+}
+
+CheckBox Polyline {
+ StrokeFill: #fff;
+}
+
+.radioGroup {
+ BorderType: BorderThickness;
+ BorderFill: rgb(220,223,230);
+ BorderThickness: 1,1,0,1;
+}
+
+ .radioGroup RadioButton {
+ BorderType: BorderThickness;
+ BorderFill: rgb(220,223,230);
+ BorderThickness: 0,0,1,0;
+ }
+
+ .radioGroup RadioButton #markPanel {
+ Visibility: Collapsed;
+ }
+
+ .radioGroup RadioButton TextBlock {
+ Margin: 5;
+ }
+
+ .radioGroup RadioButton[IsChecked=true] {
+ Background: rgb(64,158,255);
+ Foreground: #fff;
+ }
+
+.error {
+ Foreground: #f00;
+ Visibility: Collapsed;
+}
+
+ .error[DesignMode=true] {
+ Visibility: Visible;
+ }
+
+.twoLine[AttachedExtenstions.IsError=true] .error {
+ Visibility: Visible;
+}
+
+.twoLine[AttachedExtenstions.IsError=true] .textBox {
+ BorderFill: #f00;
+}
+
+ScrollBar {
+ Background: null;
+}
+
+ ScrollBar Thumb {
+ IsAntiAlias: true;
+ CornerRadius: 5;
+ }
+
+ ScrollBar[Orientation=Horizontal] {
+ Height: 12;
+ }
+
+ ScrollBar[Orientation=Vertical] {
+ Width: 12;
+ }
+
+ ScrollBar #PART_LineUpButton, ScrollBar #PART_LineDownButton {
+ Visibility: Collapsed;
+ }
+
+ComboBox {
+ Background: #fff;
+ IsAntiAlias: true;
+ BorderFill: #DCDFE6;
+ CornerRadius: 4,4,4,4;
+ BorderStroke: 1;
+}
+
+ ComboBox[IsKeyboardFocusWithin=true] {
+ BorderFill: #1E9FFF;
+ }
+
+#DropDownPanel TextBlock {
+ MarginLeft: 5;
+ MarginTop: 2;
+ MarginBottom: 2;
+}
+
+#dropDownBorder {
+ ShadowBlur: 2;
+ ShadowColor: rgba(0, 0, 0, 0.4);
+ BorderStroke: 0;
+}
+
+#DropDownPanel[IsMouseOver=false] ScrollBar {
+ Visibility: Collapsed;
+}
+
+#DropDownPanel ScrollBar[Orientation=Horizontal] {
+ Height: 10;
+}
+
+#DropDownPanel ScrollBar[Orientation=Vertical] {
+ Width: 10;
+}
+
+Slider {
+ IsAntiAlias: true;
+}
+
+ Slider Thumb {
+ IsAntiAlias: true;
+ Width: 16;
+ Height: 16;
+ CornerRadius: 7;
+ BorderFill: rgb(64,158,255);
+ BorderStroke: 2;
+ Background: #fff;
+ ZIndex: 1;
+ }
+
+
+ Slider Thumb[IsMouseOver=true] {
+ animation-name: sliderMouseOver;
+ animation-duration: 0.1s;
+ animation-iteration-count: 1;
+ animation-fill-mode: forwards;
+ }
+
+ Slider #TrackBackground {
+ CornerRadius: 2;
+ Background: rgb(228,231,237);
+ BorderStroke: 0;
+ }
+
+ Slider #decreaseRepeatButton {
+ Background: rgb(64,158,255);
+ CornerRadius: 2;
+ }
+
+ Slider[Orientation=Horizontal] #decreaseRepeatButton {
+ Height: 4;
+ MarginLeft: 5;
+ }
+
+ Slider[Orientation=Vertical] #decreaseRepeatButton {
+ Width: 4;
+ MarginBottom: 5;
+ }
+
+ProgressBar {
+ CornerRadius: 5;
+ IsAntiAlias: true;
+ BorderFill: null;
+ Background: rgb(235,238,245);
+}
+
+ ProgressBar #Indicator, ProgressBar #Animation {
+ CornerRadius: 5;
+ }
+
+NumericUpDown {
+ Background: #fff;
+ IsAntiAlias: true;
+ BorderFill: #DCDFE6;
+ CornerRadius: 4,4,4,4;
+ BorderStroke: 1;
+}
+
+ NumericUpDown RepeatButton {
+ Width: 20;
+ Background: rgb(245,247,250);
+ }
+
+ NumericUpDown #decreaseBtn {
+ CornerRadius: 4,0,0,4;
+ }
+
+ NumericUpDown #increaseBtn {
+ CornerRadius: 0,4,4,0;
+ }
+
+ NumericUpDown #textBoxBorder {
+ BorderFill: #DCDFE6;
+ }
+
+ NumericUpDown TextBox {
+ BorderStroke: 0;
+ }
+
+.widget {
+ IsAntiAlias: true;
+ BorderFill: #DCDFE6;
+ CornerRadius: 4,4,4,4;
+ BorderStroke: 1;
+}
+
+.widgetHead {
+ Background: linear-gradient(0 0,0 100%,#F7F7F7 0,#F0F0F0 1);
+ BorderType: BorderThickness;
+ BorderThickness: 0,0,0,1;
+ BorderFill: #DCDFE6;
+}
+
+DataGrid {
+ Foreground: #7a7a7a;
+}
+
+DataGridCellTemplate, DataGridRow, DataGrid, .DataGridCell {
+ BorderFill: rgb(235,238,245);
+}
+
+DataGridRow {
+ Height: 36;
+}
+
+ DataGridRow[IsMouseOver=true] {
+ Background: rgb(245,247,250);
+ }
+
+ DataGridRow[IsSelected=true] {
+ Background: rgb(245,247,250);
+ }
+
+DataGridColumnTemplate {
+ Height: 38;
+ FontSize: 15;
+ FontStyle: Bold;
+ Background: #fff;
+ BorderFill: rgb(235,238,245);
+}
+
+TabControl #headBorder {
+ Background: #fff;
+}
+
+TabItem > Border {
+ BorderThickness: 0,0,0,2;
+}
+
+TabItem[IsSelected=true] > Border {
+ BorderFill: #1E9FFF;
+}
+
+TabItem[IsSelected=true] {
+ Foreground: #1E9FFF;
+}
+
+TabControl[TabStripPlacement=Left] TabItem, TabControl[TabStripPlacement=Right] TabItem {
+ Width: 100%;
+ BorderType: BorderThickness;
+ BorderThickness: 0,0,0,1;
+ BorderFill: #e8e8e8;
+}
+
+ TabControl[TabStripPlacement=Left] TabItem TextBlock {
+ MarginRight: 0;
+ }
+
+ TabControl[TabStripPlacement=Left] TabItem > Border {
+ Width: 100%;
+ }
+
+TabControl[TabStripPlacement=Left] #headerPanel, TabControl[TabStripPlacement=Right] #headerPanel {
+ Width: 100;
+ Background: rgb(245,247,250);
+}
+
+.closeBtn[IsMouseOver=true] {
+ Fill: #171717;
+}
+
+.placeholder {
+ IsHitTestVisible: false;
+ Foreground: "192,196,204";
+ Visibility: Collapsed;
+}
+
+.textBox[AttachedExtenstions.IsEmpty=true] .placeholder {
+ Visibility: Visible;
+}
+
+.loginBox TextBox, .loginBox .placeholder {
+ FontSize: 16;
+}
+
+.loginBox CheckBox {
+ Foreground: #757575;
+}
+
+.searchBox Button {
+ CornerRadius: 0,4,4,0,
+}
+
+#MenuPop #menuPanel > Border, #MenuPop ContextMenu > Border {
+ Background: #fff;
+ ShadowColor: rgba(0, 0, 0, 0.4);
+}
+
+#MenuPop MenuItem[IsMouseOver=true] {
+ Background: #DCDFE6;
+}
+
+ListBoxItem {
+ Width: 100%;
+}
+
+#dialogClose, #dialogClose[IsMouseOver=true] {
+ Background: null;
+ BorderFill: null;
+}
+
+ #dialogClose[IsPressed=true] {
+ Background: null;
+ BorderFill: null;
+ }
+
+ #dialogClose Line {
+ StrokeFill: 218,218,218;
+ }
+
+ #dialogClose[IsMouseOver=true] Line {
+ StrokeFill: #fff;
+ }
diff --git a/CPF.Toolkit/CPF.Toolkit.csproj b/CPF.Toolkit/CPF.Toolkit.csproj
new file mode 100644
index 0000000..a49aac9
--- /dev/null
+++ b/CPF.Toolkit/CPF.Toolkit.csproj
@@ -0,0 +1,25 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CPF.Toolkit/DialogService.cs b/CPF.Toolkit/DialogService.cs
new file mode 100644
index 0000000..1c1aeba
--- /dev/null
+++ b/CPF.Toolkit/DialogService.cs
@@ -0,0 +1,63 @@
+using CPF.Controls;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace CPF.Toolkit
+{
+ public interface IDialog
+ {
+ IDialogService Dialog { get; set; }
+ }
+
+ public interface IDialogService
+ {
+ string Alert(string text, string title, DialogType dialogType, string defaultButton, params string[] buttons);
+ void Alert(string text);
+ void Sucess(string text);
+ void Error(string text);
+ void Warn(string text);
+ bool Ask(string text);
+ }
+
+ public class DialogService : IDialogService
+ {
+ public DialogService(Window owner)
+ {
+ this.owner = owner ?? throw new ArgumentNullException(nameof(owner));
+ }
+ Window owner;
+
+ public string Alert(string text, string title, DialogType dialogType, string defaultButton, params string[] buttons)
+ {
+ var view = new DialogView(text, title, dialogType, defaultButton, buttons);
+ var result = view.ShowDialogSync(owner);
+ return result?.ToString();
+ }
+
+ public void Alert(string text)
+ {
+ this.Alert(text, "消息", DialogType.None, "确定", "确定");
+ }
+
+ public bool Ask(string text)
+ {
+ return this.Alert(text, "询问", DialogType.Ask, "确定", "确定", "取消") == "确定";
+ }
+
+ public void Error(string text)
+ {
+ this.Alert(text, "错误", DialogType.Error, defaultButton: "确定", "确定");
+ }
+
+ public void Sucess(string text)
+ {
+ this.Alert(text, "成功", DialogType.Sucess, "确定", "确定");
+ }
+
+ public void Warn(string text)
+ {
+ this.Alert(text, "警告", DialogType.Warn, "确定", "确定");
+ }
+ }
+}
diff --git a/CPF.Toolkit/DialogView.cs b/CPF.Toolkit/DialogView.cs
new file mode 100644
index 0000000..51ea3cb
--- /dev/null
+++ b/CPF.Toolkit/DialogView.cs
@@ -0,0 +1,163 @@
+using CPF.Controls;
+using CPF.Drawing;
+using CPF.Input;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace CPF.Toolkit
+{
+ internal class DialogView : Window
+ {
+ public DialogView(string text, string title, DialogType dialogType, string defaultButton, params string[] buttons)
+ {
+ this.Title = title;
+ this.Text = text;
+ this.Buttons = buttons;
+ this.DefaultButton = defaultButton;
+ this.DialogType = dialogType;
+ }
+
+ public DialogType DialogType { get => GetValue(); set => SetValue(value); }
+ public string DefaultButton { get => GetValue(); set => SetValue(value); }
+ public string Text { get => GetValue(); set => SetValue(value); }
+ public string[] Buttons { get => GetValue(); set => SetValue(value); }
+
+ protected override void InitializeComponent()
+ {
+ this.ShowInTaskbar = false;
+ this.MaxWidth = 800;
+ this.MinWidth = 400;
+ this.MaxHeight = 600;
+ this.MinHeight = 250;
+ this.CanResize = false;
+ this.Width = "auto";
+ this.Height = "auto";
+ this.Background = null;
+ var frame = this.Children.Add(new WindowFrame(this, new Grid
+ {
+ Size = SizeField.Fill,
+ //LineFill = "red",
+ //LineStroke = new Stroke(1),
+ RowDefinitions =
+ {
+ new RowDefinition{ Height = "auto" },
+ new RowDefinition{ },
+ new RowDefinition{ Height = 35 },
+ },
+ Children =
+ {
+ new Picture
+ {
+ Stretch = Stretch.None,
+ Height = "70",
+ Bindings =
+ {
+ {
+ nameof(Visibility),
+ nameof(DialogType),
+ this,BindingMode.OneWay,
+ (DialogType t) => t == DialogType.None ? Visibility.Collapsed : Visibility.Visible
+ },
+ {
+ nameof(Picture.Source),
+ nameof(DialogType),
+ this,BindingMode.OneWay,
+ (DialogType t) =>
+ {
+ switch (t)
+ {
+ case DialogType.Sucess: return "res://CPF.Toolkit/Images/sucess.png";
+ case DialogType.Error:return"res://CPF.Toolkit/Images/error.png";
+ case DialogType.Ask: return"res://CPF.Toolkit/Images/ask.png";
+ case DialogType.Warn:return "res://CPF.Toolkit/Images/warn.png";
+ default:return null;
+ }
+ }
+ }
+ }
+ },
+ new TextBox
+ {
+ Attacheds = { { Grid.RowIndex,1 } },
+ BorderType = BorderType.BorderThickness,
+ BorderStroke = new Stroke(1, DashStyles.Solid),
+ BorderThickness = new Thickness(0,0,0,1),
+ //BorderFill = "Silver",
+ IsReadOnly = true,
+ Size = SizeField.Fill,
+ FontSize = 16,
+ WordWarp = true,
+ TextAlignment = TextAlignment.Center,
+ MarginTop = 30,
+ Bindings =
+ {
+ { nameof(TextBox.Text),nameof(Text),this,BindingMode.OneWay}
+ }
+ }.Assign(out var textBox),
+ new StackPanel
+ {
+ Height = "100%",
+ Attacheds = { { Grid.RowIndex,2 } },
+ MarginBottom = 4,
+ Orientation = Orientation.Horizontal,
+ }
+ .LoopCreate(this.Buttons.Length, i => new Button
+ {
+ Content = this.Buttons[i],
+ MinWidth = this.Buttons.Length <= 1 ? 80 : 65,
+ Background = "white",
+ BorderFill = "236,236,236",
+ Height = "95%",
+ MarginRight = 5,
+ Commands = { { nameof(Button.Click),(s,e) => this.DialogResult = this.Buttons[i] } }
+ }),
+ }
+ }));
+ var controlBox = frame.Find().FirstOrDefault(x => x.Name == "controlBox");
+ var caption = frame.Find().FirstOrDefault(x => x.Name == "caption");
+ var title = frame.Find().FirstOrDefault(x => x.Name == "title");
+ controlBox.Visibility = Visibility.Collapsed;
+ caption.Background = "white";
+ title.Foreground = "black";
+ textBox.TextChanged += TextBox_TextChanged;
+ }
+
+ private void TextBox_TextChanged(object sender, EventArgs e)
+ {
+ var textBox = sender as TextBox;
+ if (textBox.Document.Lines.Count > 5)
+ {
+ textBox.TextAlignment = TextAlignment.Left;
+ textBox.Height = "100%";
+ }
+ else
+ {
+ textBox.TextAlignment = TextAlignment.Center;
+ textBox.Height = "auto";
+ }
+ }
+
+ protected override void OnKeyUp(KeyEventArgs e)
+ {
+ if (e.Key == Keys.Enter || e.Key == Keys.Space)
+ {
+ var buttons = this.Find