diff --git a/CPF.Toolkit.Demo/MainView.cs b/CPF.Toolkit.Demo/MainView.cs index 36429c7..a6403e2 100644 --- a/CPF.Toolkit.Demo/MainView.cs +++ b/CPF.Toolkit.Demo/MainView.cs @@ -9,6 +9,7 @@ using CPF.Svg; using CPF.Toolkit.Dialogs; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; @@ -16,10 +17,6 @@ namespace CPF.Toolkit.Demo { public class MainView : Window { - public MainView() - { - - } MainViewModel vm = new MainViewModel(); protected override void InitializeComponent() { @@ -74,20 +71,63 @@ namespace CPF.Toolkit.Demo new Button { Content = "AsyncButton", - Commands = + Commands = { { nameof(Button.AsyncClick),async (s,e) => await this.vm.AsyncClick() } } - }.Assign(out var asyncButton), + }, + new Button + { + Content = "Mdi", + Commands = + { + { nameof(Button.Click), (s,e) => new TestMdiView().Show() } + } + }, } })); - //asyncButton.AsyncClick += AsyncButton_AsyncClick; + } + } + + internal class MainViewModel : ViewModelBase + { + public void Test() + { + this.Close(); } - private async Task AsyncButton_AsyncClick(object sender, RoutedEventArgs e) + protected override void OnClose(ClosingEventArgs e) { - await this.vm.AsyncClick(); + e.Cancel = this.Dialog.Ask("确定要关闭吗") != "确定"; + base.OnClose(e); + } + + public async void LoadingTest() + { + await this.ShowLoading(async () => + { + await Task.Delay(1000); + Debug.WriteLine(1); + await Task.Delay(1000); + Debug.WriteLine(2); + await Task.Delay(1000); + Debug.WriteLine(3); + }); + //await this.ShowLoading(Task.Delay(3000)); + + //var result = await this.ShowLoading(async () => + //{ + // await Task.Delay(5000); + // return "test"; + //}); + this.Dialog.Sucess("test"); + } + + public async Task AsyncClick() + { + await Task.Delay(3000); + this.Dialog.Alert("test"); } } } diff --git a/CPF.Toolkit.Demo/MainViewModel.cs b/CPF.Toolkit.Demo/MainViewModel.cs deleted file mode 100644 index 3470b28..0000000 --- a/CPF.Toolkit.Demo/MainViewModel.cs +++ /dev/null @@ -1,57 +0,0 @@ -using CPF.Controls; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace CPF.Toolkit.Demo -{ - internal class MainViewModel : ViewModelBase - { - bool isClose = false; - public void Test() - { - if (this.Dialog.Ask("确定要关闭吗") == "确定") - { - this.isClose = true; - this.Close(); - } - } - - protected override void OnClose(ClosingEventArgs e) - { - e.Cancel = !this.isClose; - base.OnClose(e); - } - - public async void LoadingTest() - { - await this.ShowLoading(async () => - { - await Task.Delay(1000); - Debug.WriteLine(1); - await Task.Delay(1000); - Debug.WriteLine(2); - await Task.Delay(1000); - Debug.WriteLine(3); - }); - //await this.ShowLoading(Task.Delay(3000)); - this.Dialog.Sucess("test"); - - //var result = await this.ShowLoading(async () => - //{ - // await Task.Delay(5000); - // return "test"; - //}); - //this.Dialog.Sucess(result); - } - - public async Task AsyncClick() - { - await Task.Delay(3000); - this.Dialog.Alert("test"); - } - } -} diff --git a/CPF.Toolkit.Demo/Program.cs b/CPF.Toolkit.Demo/Program.cs index e83b91c..6ae9276 100644 --- a/CPF.Toolkit.Demo/Program.cs +++ b/CPF.Toolkit.Demo/Program.cs @@ -17,7 +17,7 @@ namespace CPF.Toolkit.Demo , (OperatingSystemType.Linux, new CPF.Linux.LinuxPlatform(), new SkiaDrawingFactory { UseGPU = false }) ); - Application.Run(ViewManager.View()); + Application.Run(ViewManager.View()); } } } diff --git a/CPF.Toolkit.Demo/TestMdiView.cs b/CPF.Toolkit.Demo/TestMdiView.cs index 8d02f31..77e7c97 100644 --- a/CPF.Toolkit.Demo/TestMdiView.cs +++ b/CPF.Toolkit.Demo/TestMdiView.cs @@ -7,8 +7,10 @@ using CPF.Shapes; using CPF.Styling; using CPF.Svg; using CPF.Toolkit.Controls; +using CPF.Toolkit.Dialogs; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; @@ -23,19 +25,114 @@ namespace CPF.Toolkit.Demo this.Width = 1280; this.Height = 720; this.Background = null; - var frame = this.Children.Add(new WindowFrame(this, new MdiHost + var frame = this.Children.Add(new WindowFrame(this, new Grid { + Size = SizeField.Fill, + RowDefinitions = + { + new RowDefinition{ Height = 30 }, + new RowDefinition{ }, + }, Children = { - new MdiWindow{ Content = new Grid{ }, Title = "test1"}, - //new MdiWindow{ Content = new Grid{ }, Title = "test2"}, - //new MdiWindow{ Content = new Grid{ }, Title = "test3"}, + new MdiHost + { + Size = SizeField.Fill, + Attacheds = { { Grid.RowIndex,1 } } + }.Assign(out var host), + new WrapPanel + { + Orientation = Orientation.Horizontal, + Size = SizeField.Fill, + Children = + { + new Button + { + Height = "100%", + Content = "New Window", + [nameof(Button.Click)] = new CommandDescribe((s,e) => host.Children.Add(new M{ Title = $"Title{host.Children.Count}", })), + }, + new Button + { + Height = "100%", + Content = "任务栏居上", + [nameof(Button.Click)] = new CommandDescribe((s,e) => host.TaskBarPlacement = TaskBarPlacement.Top), + }, + new Button + { + Height = "100%", + Content = "任务栏居下", + [nameof(Button.Click)] = new CommandDescribe((s,e) => host.TaskBarPlacement = TaskBarPlacement.Bottom), + }, + }, + }, }, })); - frame.CaptionBackgrund = "white"; - frame.CaptionForeground = "black"; - frame.ControlBoxStroke = "black"; + //frame.CaptionBackgrund = "white"; + //frame.CaptionForeground = "black"; + //frame.ControlBoxStroke = "black"; frame.MaximizeBox = true; } } + + internal class M : MdiWindow + { + protected override void InitializeComponent() + { + var vm = new MV { Dialog = new DialogService(this.Root as Window) }; + this.DataContext = vm; + this.CommandContext = vm; + this.Content = new WrapPanel + { + Size = SizeField.Fill, + Children = + { + new Button + { + Content = "close", + [nameof(Button.Click)] = new CommandDescribe((s,e) => vm.TestClose()) + }, + new Button + { + Content = "loading", + [nameof(Button.AsyncClick)] = new CommandDescribe(async (s,e) => await vm.LoadingTest()), + }, + new Button + { + Content = "alert", + [nameof(Button.Click)] = new CommandDescribe( (s,e) => vm.TestAlert()), + }, + }, + }; + } + } + + internal class MV : ViewModelBase + { + public void TestClose() + { + this.Close(); + } + + public void TestAlert() + { + this.Dialog.Warn("test"); + } + + public async Task LoadingTest() + { + var result = await this.ShowLoading(async () => + { + await Task.Delay(3000); + return "ok"; + }); + Debug.WriteLine(result); + } + + protected override void OnClose(ClosingEventArgs e) + { + e.Cancel = this.Dialog.Ask("确定要关闭吗") != "确定"; + base.OnClose(e); + } + } } diff --git a/CPF.Toolkit/Controls/MdiHost.cs b/CPF.Toolkit/Controls/MdiHost.cs index 470edc2..f052d8d 100644 --- a/CPF.Toolkit/Controls/MdiHost.cs +++ b/CPF.Toolkit/Controls/MdiHost.cs @@ -2,6 +2,7 @@ using CPF.Drawing; using CPF.Platform; using CPF.Shapes; +using CPF.Toolkit.Dialogs; using System; using System.Collections.Generic; using System.Diagnostics; @@ -18,10 +19,9 @@ namespace CPF.Toolkit.Controls this.Size = SizeField.Fill; this.Background = "204,204,204"; base.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star }); - base.RowDefinitions.Add(new RowDefinition { Height = "35", MaxHeight = 35 }); - + base.RowDefinitions.Add(new RowDefinition { Height = 35 }); base.Children.Add(this.host); - var taskBar = base.Children.Add(new ListBox + taskBar = base.Children.Add(new ListBox { Size = SizeField.Fill, Background = "white", @@ -47,12 +47,16 @@ namespace CPF.Toolkit.Controls this.host.UIElementAdded += Host_UIElementAdded; this.host.UIElementRemoved += Host_UIElementRemoved; } - Dictionary normalRect = new Dictionary(); - readonly Panel host = new Panel { Size = SizeField.Fill }; + readonly Dictionary normalRect = []; + readonly Panel host = new() { Size = SizeField.Fill }; + readonly ListBox taskBar; Collection TaskBarList { get => GetValue>(); set => SetValue(value); } public new UIElementCollection Children => host.Children; public MdiWindow SelectWindow { get => GetValue(); set => SetValue(value); } + [PropertyMetadata(TaskBarPlacement.Bottom)] + public TaskBarPlacement TaskBarPlacement { get => GetValue(); set => SetValue(value); } + protected override void OnPropertyChanged(string propertyName, object oldValue, object newValue, PropertyMetadataAttribute propertyMetadata) { if (propertyName == nameof(this.SelectWindow) && this.SelectWindow != null) @@ -60,6 +64,26 @@ namespace CPF.Toolkit.Controls this.Topping(this.SelectWindow); this.SelectWindow.WindowState = this.normalRect[this.SelectWindow].OldState; } + else if (propertyName == nameof(this.TaskBarPlacement) && this.taskBar != null) + { + this.RowDefinitions.Clear(); + this.ColumnDefinitions.Clear(); + switch ((TaskBarPlacement)newValue) + { + case TaskBarPlacement.Top: + this.RowDefinitions.Add(new RowDefinition { Height = 35 }); + this.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star }); + RowIndex(this.taskBar,0); + RowIndex(this.host, 1); + break; + case TaskBarPlacement.Bottom: + this.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star }); + this.RowDefinitions.Add(new RowDefinition { Height = 35 }); + RowIndex(this.host,0); + RowIndex(this.taskBar, 1); + break; + } + } base.OnPropertyChanged(propertyName, oldValue, newValue, propertyMetadata); } @@ -86,8 +110,10 @@ namespace CPF.Toolkit.Controls private void Host_UIElementRemoved(object sender, UIElementRemovedEventArgs e) { - e.Element.PropertyChanged -= Element_PropertyChanged; - e.Element.PreviewMouseDown -= Element_PreviewMouseDown; + var view = e.Element as MdiWindow; + view.PropertyChanged -= Element_PropertyChanged; + view.PreviewMouseDown -= Element_PreviewMouseDown; + view.Closing -= View_Closing; this.TaskBarList.Remove(e.Element); this.normalRect.Remove(e.Element); } @@ -98,11 +124,43 @@ namespace CPF.Toolkit.Controls this.normalRect.Add(e.Element, new MdiWindowRect { Left = 0, Top = 0, Height = 500, Width = 500 }); view.PropertyChanged += Element_PropertyChanged; view.PreviewMouseDown += Element_PreviewMouseDown; + view.Closing += View_Closing; this.TaskBarList.Add(view); e.Element.ZIndex = this.host.Children.Max(x => x.ZIndex) + 1; this.Topping(view); } + private void View_Closing(object sender, ClosingEventArgs e) + { + if (e.Cancel) return; + UIElement mdiWindow = null; + if (sender is IClosable closable) + { + mdiWindow = this.host.Children.FirstOrDefault(x => x.DataContext == closable); + } + else if (sender is MdiWindow mdi) + { + mdiWindow = mdi; + } + if (mdiWindow != null) + { + if (mdiWindow == this.SelectWindow) + { + this.BeginInvoke(() => + { + if (this.host.Children.Count == 0) return; + var index = this.host.Children.Where(x => x.Visibility == Visibility.Visible).Max(x => x.ZIndex); + if (index != -1) + { + this.SelectWindow = this.host.Children.Find(x => x.ZIndex == index) as MdiWindow; + } + }); + } + this.host.Children.Remove(mdiWindow); + mdiWindow.Dispose(); + } + } + private void Element_PreviewMouseDown(object sender, Input.MouseButtonEventArgs e) { var ele = (MdiWindow)sender; @@ -181,6 +239,7 @@ namespace CPF.Toolkit.Controls public void Topping(MdiWindow ele) { if (ele == null) return; + ele.Focus(); var index = this.host.Children.Max(x => x.ZIndex); if (ele.ZIndex == index) { diff --git a/CPF.Toolkit/Controls/MdiWindow.cs b/CPF.Toolkit/Controls/MdiWindow.cs index 425aa07..e726853 100644 --- a/CPF.Toolkit/Controls/MdiWindow.cs +++ b/CPF.Toolkit/Controls/MdiWindow.cs @@ -8,10 +8,12 @@ using CPF.Platform; using CPF.Shapes; using CPF.Styling; using CPF.Svg; +using CPF.Toolkit.Dialogs; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Reflection; using System.Security.Cryptography; using System.Text; @@ -19,6 +21,10 @@ namespace CPF.Toolkit.Controls { public class MdiWindow : Control { + public MdiWindow() + { + this.Init(); + } public WindowState WindowState { get => GetValue(); set => SetValue(value); } public UIElement Content { get => GetValue(); set => SetValue(value); } @@ -37,25 +43,43 @@ namespace CPF.Toolkit.Controls [UIPropertyMetadata((byte)5, UIPropertyOptions.AffectsMeasure)] public byte ShadowBlur { get { return GetValue(); } set { SetValue(value); } } + [PropertyMetadata(true)] + public bool CanResize + { + get => GetValue(); + set + { + SetValue(value); + if (!value) this.MaximizeBox = false; + } + } + public event EventHandler Closing; - protected override void InitializeComponent() + + void Init() { - var bar = (ViewFill)"154,180,208"; - var thubmEnabled = new BindingDescribe(this, nameof(WindowState), BindingMode.OneWay, b => ((WindowState)b) == WindowState.Normal); + this.Focusable = true; + var borderColor = (ViewFill)"152,180,208"; + var lostFocusBorderColor = (ViewFill)"214,227,241"; + var dragEnabled = new BindingDescribe(this, nameof(WindowState), BindingMode.OneWay, x => + { + if (this.CanResize) + { + return ((WindowState)x) == WindowState.Normal; + } + return false; + }); this.Size = new SizeField(500, 500); this.Background = null; this.MarginLeft = 0; this.MarginTop = 0; - this.MinWidth = 200; - this.MinHeight = 70; this.ClipToBounds = true; this.Children.Add(new Border { Size = SizeField.Fill, - Background = "#fff", + Background = "white", BorderType = BorderType.BorderStroke, - BorderStroke = new Stroke(0), ShadowBlur = ShadowBlur, ShadowColor = Color.FromRgba(0, 0, 0, 150), Child = new Decorator @@ -84,76 +108,140 @@ namespace CPF.Toolkit.Controls { Name = "top", Size = "100%,5", - Background = bar, Cursor = Cursors.SizeNorthSouth, - Attacheds = { { Grid.ColumnSpan,3 } }, - [nameof(IsEnabled)] = thubmEnabled, - Commands = + Attacheds = { { Grid.ColumnIndex,1 } }, + [nameof(IsEnabled)] = dragEnabled, + [nameof(Background)] = new BindingDescribe(this,nameof(IsFocused),BindingMode.OneWay ,x => ((bool)x) ? borderColor : lostFocusBorderColor), + [nameof(Thumb.DragDelta)] = new CommandDescribe((s,e) => { + var args = e as DragDeltaEventArgs; + if (this.Height.Value - args.VerticalChange > 0) { - nameof(Thumb.DragDelta),(s,e) => - { - var args = e as DragDeltaEventArgs; - if (this.Height.Value - args.VerticalChange > 0) - { - this.MarginTop += args.VerticalChange; - this.Height -= args.VerticalChange; - } - } + this.MarginTop += args.VerticalChange; + this.Height -= args.VerticalChange; } - }, + }), }, new Thumb { Name = "left", Size = "5,100%", - Background = bar, Cursor = Cursors.SizeWestEast, - IsEnabled = false, - Attacheds = { { Grid.ColumnIndex,0 } ,{ Grid.RowSpan,4 } }, - [nameof(IsEnabled)] = thubmEnabled, - Commands = + Attacheds = { { Grid.RowIndex,1 },{ Grid.RowSpan,2 } }, + [nameof(IsEnabled)] = dragEnabled, + [nameof(Background)] = new BindingDescribe(this,nameof(IsFocused),BindingMode.OneWay ,x => ((bool)x) ? borderColor : lostFocusBorderColor), + [nameof(Thumb.DragDelta)] = new CommandDescribe((s,e) => { + var args = e as DragDeltaEventArgs; + if (this.Width.Value - args.HorizontalChange > 0) { - nameof(Thumb.DragDelta),(s,e) => - { - var args = e as DragDeltaEventArgs; - if (this.Width.Value - args.HorizontalChange > 0) - { - this.MarginLeft += args.HorizontalChange; - this.Width -= args.HorizontalChange; - } - } + this.MarginLeft += args.HorizontalChange; + this.Width -= args.HorizontalChange; } - } + }), + }, + new Thumb + { + Name = "left_top", + Size = SizeField.Fill, + Cursor = Cursors.TopLeftCorner, + [nameof(IsEnabled)] = dragEnabled, + [nameof(Background)] = new BindingDescribe(this,nameof(IsFocused),BindingMode.OneWay ,x => ((bool)x) ? borderColor : lostFocusBorderColor), + [nameof(Thumb.DragDelta)] = new CommandDescribe((s,e) => + { + var args = e as DragDeltaEventArgs; + if (this.Width.Value - args.HorizontalChange > 0 && this.Height.Value - args.VerticalChange > 0) + { + this.MarginLeft += args.HorizontalChange; + this.MarginTop += args.VerticalChange; + this.Width -= args.HorizontalChange; + this.Height -= args.VerticalChange; + } + }), }, new Thumb { Name = "right", Size = "5,100%", - Background = bar, Cursor = Cursors.SizeWestEast, MarginRight = 0, - Attacheds = { { Grid.ColumnIndex,2 },{ Grid.RowSpan,4 } }, - [nameof(IsEnabled)] = thubmEnabled, - Commands = { { nameof(Thumb.DragDelta),(s,e) => this.Width += (e as DragDeltaEventArgs).HorizontalChange } } + Attacheds = { { Grid.ColumnIndex,2 },{ Grid.RowIndex,1 },{ Grid.RowSpan,2 } }, + [nameof(IsEnabled)] = dragEnabled, + [nameof(Thumb.DragDelta)] = new CommandDescribe((s,e) => this.Width += (e as DragDeltaEventArgs).HorizontalChange), + [nameof(Background)] = new BindingDescribe(this,nameof(IsFocused),BindingMode.OneWay ,x => ((bool)x) ? borderColor : lostFocusBorderColor), + }, + new Thumb + { + Name = "right_top", + Size = SizeField.Fill, + Cursor = Cursors.TopRightCorner, + MarginRight = 0, + Attacheds = { { Grid.ColumnIndex,2 } }, + [nameof(IsEnabled)] = dragEnabled, + [nameof(Background)] = new BindingDescribe(this,nameof(IsFocused),BindingMode.OneWay ,x => ((bool)x) ? borderColor : lostFocusBorderColor), + [nameof(Thumb.DragDelta)] = new CommandDescribe((s,e) => + { + var args = e as DragDeltaEventArgs; + if (this.Width.Value - args.HorizontalChange > 0 && this.Height.Value - args.VerticalChange > 0) + { + this.MarginTop += args.VerticalChange; + this.Width += args.HorizontalChange; + this.Height -= args.VerticalChange; + } + }), }, new Thumb { Name = "bottom", Size = "100%,5", - Background = bar, Cursor = Cursors.SizeNorthSouth, - Attacheds = { { Grid.RowIndex,3 },{ Grid.ColumnSpan,3 } }, - [nameof(IsEnabled)] = thubmEnabled, - Commands = { { nameof(Thumb.DragDelta),(s,e) => this.Height += (e as DragDeltaEventArgs).VerticalChange } } + Attacheds = { { Grid.RowIndex,3 },{ Grid.ColumnIndex,1 } }, + [nameof(IsEnabled)] = dragEnabled, + [nameof(Thumb.DragDelta)] = new CommandDescribe((s,e) => this.Height += (e as DragDeltaEventArgs).VerticalChange), + [nameof(Background)] = new BindingDescribe(this,nameof(IsFocused),BindingMode.OneWay ,x => ((bool)x) ? borderColor : lostFocusBorderColor), + }, + new Thumb + { + Name = "left_bottom", + Size = SizeField.Fill, + Cursor = Cursors.BottomLeftCorner, + Attacheds = { { Grid.RowIndex,3 } }, + [nameof(Background)] = new BindingDescribe(this,nameof(IsFocused),BindingMode.OneWay ,x => ((bool)x) ? borderColor : lostFocusBorderColor), + [nameof(IsEnabled)] = dragEnabled, + [nameof(Thumb.DragDelta)] = new CommandDescribe((s,e) => + { + var args = e as DragDeltaEventArgs; + if (this.Width.Value - args.HorizontalChange > 0 && this.Height.Value + args.VerticalChange > 0) + { + this.MarginLeft += args.HorizontalChange; + this.Width -= args.HorizontalChange; + this.Height += args.VerticalChange; + } + }), + }, + new Thumb + { + Name = "right_bottom", + Size = SizeField.Fill, + Cursor = Cursors.BottomRightCorner, + Attacheds = { { Grid.RowIndex,3 },{ Grid.ColumnIndex,2 } }, + [nameof(Background)] = new BindingDescribe(this,nameof(IsFocused),BindingMode.OneWay ,x => ((bool)x) ? borderColor : lostFocusBorderColor), + [nameof(IsEnabled)] = dragEnabled, + [nameof(Thumb.DragDelta)] = new CommandDescribe((s,e) => + { + var args = e as DragDeltaEventArgs; + if (this.Height.Value + args.VerticalChange > 0 && this.Width.Value + args.HorizontalChange > 0) + { + this.Width += args.HorizontalChange; + this.Height += args.VerticalChange; + } + }), }, new Thumb { Name = "caption", Attacheds = { { Grid.RowIndex,1 },{ Grid.ColumnIndex,1 } }, Size = SizeField.Fill, - Background = bar, Child = new Panel { Size = SizeField.Fill, @@ -193,8 +281,8 @@ namespace CPF.Toolkit.Controls IsAntiAlias = true, StrokeFill = "black" }, - [nameof(Visibility)] = new BindingDescribe(this,nameof(MinimizeBox),BindingMode.OneWay,a=>(bool)a?Visibility.Visible: Visibility.Collapsed), - Commands = { { nameof(Button.Click),(s,e) => this.WindowState = WindowState.Minimized } }, + [nameof(Visibility)] = new BindingDescribe(this,nameof(MinimizeBox),BindingMode.OneWay,x=>(bool)x?Visibility.Visible: Visibility.Collapsed), + [nameof(Button.Click)] = new CommandDescribe((s,e) => this.WindowState = WindowState.Minimized) }, new Panel { @@ -212,12 +300,13 @@ namespace CPF.Toolkit.Controls MarginTop = 5, StrokeStyle = "2", }, - Commands = { { nameof(Button.Click),(s,e) => this.WindowState = WindowState.Maximized } }, - [nameof(Visibility)] = new BindingDescribe(this, - nameof(WindowState), - BindingMode.OneWay, - a => ((WindowState)a).Or(WindowState.Maximized,WindowState.FullScreen) - ? Visibility.Collapsed : Visibility.Visible), + [nameof(Button.Click)] = new CommandDescribe((s, e) => this.WindowState = WindowState.Maximized), + [nameof(Visibility)] = + new BindingDescribe( + this, + nameof(WindowState), + BindingMode.OneWay, + x => ((WindowState)x).Or(WindowState.Maximized,WindowState.FullScreen) ? Visibility.Collapsed : Visibility.Visible), }, new SystemButton { @@ -252,13 +341,13 @@ namespace CPF.Toolkit.Controls } } }, - Commands = { { nameof(Button.Click),(s,e) => this.WindowState = WindowState.Normal } }, - [nameof(Visibility)] = new BindingDescribe(this, - nameof(WindowState), - BindingMode.OneWay, - a => ((WindowState)a).Or( WindowState.Normal, WindowState.Minimized) - ? Visibility.Collapsed : - Visibility.Visible) + [nameof(Button.Click)] = new CommandDescribe((s, e) => this.WindowState = WindowState.Normal), + [nameof(Visibility)] = + new BindingDescribe( + this, + nameof(WindowState), + BindingMode.OneWay, + x => ((WindowState)x).Or(WindowState.Normal,WindowState.Minimized)? Visibility.Collapsed : Visibility.Visible) } } }, @@ -291,79 +380,98 @@ namespace CPF.Toolkit.Controls } } }, - Commands = - { - { - nameof(Button.Click),(ss,ee) => - { - var e = new ClosingEventArgs(); - this.Closing?.Invoke(this,e); - if (!e.Cancel) - { - this.Visibility = Visibility.Collapsed; - this.Dispose(); - } - } - } - }, - [nameof(Visibility)] = new BindingDescribe(this,nameof(this.CloseBox),BindingMode.OneWay,a=>(bool)a?Visibility.Visible: Visibility.Collapsed) + [nameof(Button.Click)] = new CommandDescribe((ss,ee) => this.Close()), + [nameof(Visibility)] = new BindingDescribe(this,nameof(this.CloseBox),BindingMode.OneWay,x=>(bool)x?Visibility.Visible: Visibility.Collapsed) } } }, }, }, - Commands = + [nameof(Thumb.DragDelta)] = new CommandDescribe((ss,ee)=> { + if (this.WindowState.Or(WindowState.Normal)) { - nameof(Thumb.DragDelta), - (s,e) => - { - if (this.WindowState.Or(WindowState.Normal)) - { - var arge = e as DragDeltaEventArgs; - this.MarginLeft += arge.HorizontalChange; - this.MarginTop += arge.VerticalChange; - } - } - }, - { - nameof(DoubleClick), - (s,e) => this.Delay(TimeSpan.FromMilliseconds(150),() => - { - if (this.WindowState.Or(WindowState.Maximized,WindowState.Minimized)) - { - this.WindowState = WindowState.Normal; - } - else if (this.WindowState == WindowState.Normal) - { - this.WindowState = WindowState.Maximized; - } - }) + var arge = ee as DragDeltaEventArgs; + this.MarginLeft += arge.HorizontalChange; + this.MarginTop += arge.VerticalChange; } - }, + }), + [nameof(DoubleClick)] = new CommandDescribe((ss,ee) => this.Delay(TimeSpan.FromMilliseconds(150),()=> + { + if(!this.MaximizeBox) return; + if (this.WindowState.Or(WindowState.Maximized,WindowState.Minimized)) + { + this.WindowState = WindowState.Normal; + } + else if (this.WindowState == WindowState.Normal) + { + this.WindowState = WindowState.Maximized; + } + })), + [nameof(Background)] = new BindingDescribe(this,nameof(IsFocused),BindingMode.OneWay ,x => ((bool)x) ? borderColor : lostFocusBorderColor) }, new Decorator { Attacheds = { { Grid.RowIndex,2 } ,{ Grid.ColumnIndex,1 } }, Size = SizeField.Fill, - Child = this.Content, + [nameof(Decorator.Child)] = new BindingDescribe(this,nameof(Content)) }, } }, }, - [nameof(Border.ShadowBlur)] = new BindingDescribe(this, - nameof(WindowState), - BindingMode.OneWay, - a => ((WindowState)a).Or(WindowState.Maximized, WindowState.FullScreen) ? 0 : ShadowBlur), + [nameof(ShadowBlur)] = new BindingDescribe(this, nameof(WindowState), BindingMode.OneWay, x => ((WindowState)x).Or(WindowState.Maximized, WindowState.FullScreen) ? 0 : ShadowBlur), + [nameof(ShadowBlur)] = new BindingDescribe(this, nameof(IsFocused), BindingMode.OneWay, x => ((bool)x) ? ShadowBlur : 0), + [nameof(BorderStroke)] = new BindingDescribe(this, nameof(IsFocused), BindingMode.OneWay, x => ((bool)x) ? "0" : "1"), + [nameof(BorderFill)] = new BindingDescribe(this, nameof(IsFocused), BindingMode.OneWay, x => ((bool)x) ? null : "0,0,0,100"), }); - - this.Content.Margin = "0"; - this.Content.ClipToBounds = true; } - public override string ToString() + protected override void OnPropertyChanged(string propertyName, object oldValue, object newValue, PropertyMetadataAttribute propertyMetadata) { - return this.Title; + if (propertyName == nameof(DataContext) && newValue != null) + { + if (newValue is IClosable closable) + { + closable.Closable -= Closable_Closable; + closable.Closable += Closable_Closable; + } + if (newValue is ILoading loading) + { + loading.CreateLoading(this); + } + } + else if (propertyName == nameof(Content) && newValue != null) + { + this.Content.Margin = "0"; + this.Content.ClipToBounds = true; + } + base.OnPropertyChanged(propertyName, oldValue, newValue, propertyMetadata); + } + + private void Closable_Closable(object sender, ClosingEventArgs e) + { + this.DoClose(sender, e); + } + + public void Close() + { + if (this.Closing != null) + { + this.DoClose(this, new ClosingEventArgs()); + } + else + { + this.Dispose(); + } + } + + void DoClose(object sender, ClosingEventArgs e) + { + if (this.DataContext is IClosable closable) + { + closable.OnClosable(sender, e); + } + this.Closing.Invoke(sender, e); } } } diff --git a/CPF.Toolkit/Controls/TaskBarPlacement.cs b/CPF.Toolkit/Controls/TaskBarPlacement.cs new file mode 100644 index 0000000..9d1ba9e --- /dev/null +++ b/CPF.Toolkit/Controls/TaskBarPlacement.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CPF.Toolkit.Controls +{ + public enum TaskBarPlacement + { + Top, + Bottom, + } +} diff --git a/CPF.Toolkit/Dialogs/IClosable.cs b/CPF.Toolkit/Dialogs/IClosable.cs index 374004d..001c99f 100644 --- a/CPF.Toolkit/Dialogs/IClosable.cs +++ b/CPF.Toolkit/Dialogs/IClosable.cs @@ -8,7 +8,7 @@ namespace CPF.Toolkit.Dialogs { internal interface IClosable { - event EventHandler Closable; + event EventHandler Closable; void OnClosable(object sender, ClosingEventArgs e); } } diff --git a/CPF.Toolkit/ToolkitHelper.cs b/CPF.Toolkit/ToolkitHelper.cs new file mode 100644 index 0000000..3cc7198 --- /dev/null +++ b/CPF.Toolkit/ToolkitHelper.cs @@ -0,0 +1,46 @@ +using CPF.Controls; +using CPF.Toolkit.Dialogs; +using System; +using System.Collections.Generic; +using System.Text; + +namespace CPF.Toolkit +{ + public static class ToolkitHelper + { + + internal static void CreateLoading(this ILoading loading,UIElement uIElement) + { + loading.ShowLoadingFunc += async (message, task) => + { + var loadingBox = new LoadingBox { Message = message }; + var layer = new LayerDialog + { + Name = "loadingDialog", + Content = loadingBox, + ShowCloseButton = false, + Background = null, + }; + layer.ShowDialog(uIElement); + dynamic t = task; + var result = await t; + loadingBox.Invoke(layer.CloseDialog); + return result; + }; + loading.ShowLoading += async (message, task) => + { + var loadingBox = new LoadingBox { Message = message }; + var layer = new LayerDialog + { + Name = "loadingDialog", + Content = loadingBox, + ShowCloseButton = false, + Background = null, + }; + layer.ShowDialog(uIElement); + await task; + loadingBox.Invoke(layer.CloseDialog); + }; + } + } +} diff --git a/CPF.Toolkit/ViewManager.cs b/CPF.Toolkit/ViewManager.cs index 6eccb24..b1d9be7 100644 --- a/CPF.Toolkit/ViewManager.cs +++ b/CPF.Toolkit/ViewManager.cs @@ -24,12 +24,8 @@ namespace CPF.Toolkit { if (view.DataContext is IClosable closable) { - closable.Closable += (ss, dialogResult) => + closable.Closable += (ss, ee) => { - if (view.IsDialogMode == true) - { - view.DialogResult = dialogResult; - } view.Close(); }; } @@ -39,40 +35,9 @@ namespace CPF.Toolkit } if (view.DataContext is ILoading loading) { - loading.ShowLoadingFunc += async (message, task) => - { - var loadingBox = new LoadingBox { Message = message }; - var layer = new LayerDialog - { - Name = "loadingDialog", - Content = loadingBox, - ShowCloseButton = false, - Background = null, - }; - layer.ShowDialog(view); - dynamic t = task; - var result = await t; - loadingBox.Invoke(layer.CloseDialog); - return (object)result; - }; - loading.ShowLoading += async (message, task) => - { - var loadingBox = new LoadingBox { Message = message }; - var layer = new LayerDialog - { - Name = "loadingDialog", - Content = loadingBox, - ShowCloseButton = false, - Background = null, - }; - layer.ShowDialog(view); - await task; - loadingBox.Invoke(layer.CloseDialog); - }; + loading.CreateLoading(view); } } - - } private static void View_Closing(object sender, ClosingEventArgs e) diff --git a/CPF.Toolkit/ViewModelBase.cs b/CPF.Toolkit/ViewModelBase.cs index 0688165..4ceced5 100644 --- a/CPF.Toolkit/ViewModelBase.cs +++ b/CPF.Toolkit/ViewModelBase.cs @@ -9,10 +9,10 @@ namespace CPF.Toolkit { public class ViewModelBase : ObservableObject, IClosable, IDialog, ILoading { - event EventHandler _close; + event EventHandler _close; event Func> _showLoadingFunc; event Func _showLading; - event EventHandler IClosable.Closable { add => this._close += value; remove => this._close -= value; } + event EventHandler IClosable.Closable { add => this._close += value; remove => this._close -= value; } event Func> ILoading.ShowLoadingFunc { add => this._showLoadingFunc += value; remove => this._showLoadingFunc -= value; } event Func ILoading.ShowLoading { add => this._showLading += value; remove => this._showLading -= value; } @@ -20,10 +20,10 @@ namespace CPF.Toolkit public IDialogService Dialog { get; set; } - protected void Close(object dialogResult = null) + protected void Close() { if (this._close == null) throw new ArgumentNullException(); - this._close.Invoke(this, dialogResult); + this._close.Invoke(this, new ClosingEventArgs()); } protected virtual void OnClose(ClosingEventArgs e) { } diff --git a/CPF/BindingDescribe.cs b/CPF/BindingDescribe.cs index d4dfb74..87b18be 100644 --- a/CPF/BindingDescribe.cs +++ b/CPF/BindingDescribe.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using System.ComponentModel; using System.Linq.Expressions; +using System.Threading.Tasks; namespace CPF { @@ -17,7 +18,7 @@ namespace CPF { PropertyName = sourceProperty; } - + public BindingDescribe(string sourceProperty, BindingMode binding) { PropertyName = sourceProperty; @@ -401,6 +402,7 @@ namespace CPF public class CommandDescribe { public Action Action { get; set; } + public Func AsyncAction { get; set; } public string MethodName { get; set; } public object[] Parameters { get; set; } @@ -416,6 +418,11 @@ namespace CPF { Action = command; } + + public CommandDescribe(Func command) + { + this.AsyncAction = command; + } /// /// 定义个命令绑定 /// diff --git a/CPF/CpfObject.cs b/CPF/CpfObject.cs index d863b7f..b6dfdc5 100644 --- a/CPF/CpfObject.cs +++ b/CPF/CpfObject.cs @@ -194,6 +194,10 @@ namespace CPF { if (value.Command != null) { + if (value.Command.AsyncAction != null) + { + Commands.Add(propertyName, value.Command.AsyncAction); + } if (value.Command.Action != null) { Commands.Add(propertyName, value.Command.Action);