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