This commit is contained in:
luxiaoqi 2023-11-29 17:07:17 +08:00
parent 6631fec5e6
commit a1db3807ff
13 changed files with 517 additions and 236 deletions

View File

@ -9,6 +9,7 @@ using CPF.Svg;
using CPF.Toolkit.Dialogs; using CPF.Toolkit.Dialogs;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -16,10 +17,6 @@ namespace CPF.Toolkit.Demo
{ {
public class MainView : Window public class MainView : Window
{ {
public MainView()
{
}
MainViewModel vm = new MainViewModel(); MainViewModel vm = new MainViewModel();
protected override void InitializeComponent() protected override void InitializeComponent()
{ {
@ -74,20 +71,63 @@ namespace CPF.Toolkit.Demo
new Button new Button
{ {
Content = "AsyncButton", Content = "AsyncButton",
Commands = Commands =
{ {
{ nameof(Button.AsyncClick),async (s,e) => await this.vm.AsyncClick() } { 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");
} }
} }
} }

View File

@ -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");
}
}
}

View File

@ -17,7 +17,7 @@ namespace CPF.Toolkit.Demo
, (OperatingSystemType.Linux, new CPF.Linux.LinuxPlatform(), new SkiaDrawingFactory { UseGPU = false }) , (OperatingSystemType.Linux, new CPF.Linux.LinuxPlatform(), new SkiaDrawingFactory { UseGPU = false })
); );
Application.Run(ViewManager.View<TestMdiView>()); Application.Run(ViewManager.View<MainView>());
} }
} }
} }

View File

@ -7,8 +7,10 @@ using CPF.Shapes;
using CPF.Styling; using CPF.Styling;
using CPF.Svg; using CPF.Svg;
using CPF.Toolkit.Controls; using CPF.Toolkit.Controls;
using CPF.Toolkit.Dialogs;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -23,19 +25,114 @@ namespace CPF.Toolkit.Demo
this.Width = 1280; this.Width = 1280;
this.Height = 720; this.Height = 720;
this.Background = null; 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 = Children =
{ {
new MdiWindow{ Content = new Grid{ }, Title = "test1"}, new MdiHost
//new MdiWindow{ Content = new Grid{ }, Title = "test2"}, {
//new MdiWindow{ Content = new Grid{ }, Title = "test3"}, 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.CaptionBackgrund = "white";
frame.CaptionForeground = "black"; //frame.CaptionForeground = "black";
frame.ControlBoxStroke = "black"; //frame.ControlBoxStroke = "black";
frame.MaximizeBox = true; 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);
}
}
} }

View File

@ -2,6 +2,7 @@
using CPF.Drawing; using CPF.Drawing;
using CPF.Platform; using CPF.Platform;
using CPF.Shapes; using CPF.Shapes;
using CPF.Toolkit.Dialogs;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@ -18,10 +19,9 @@ namespace CPF.Toolkit.Controls
this.Size = SizeField.Fill; this.Size = SizeField.Fill;
this.Background = "204,204,204"; this.Background = "204,204,204";
base.RowDefinitions.Add(new RowDefinition { Height = GridLength.Star }); 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); base.Children.Add(this.host);
var taskBar = base.Children.Add(new ListBox taskBar = base.Children.Add(new ListBox
{ {
Size = SizeField.Fill, Size = SizeField.Fill,
Background = "white", Background = "white",
@ -47,12 +47,16 @@ namespace CPF.Toolkit.Controls
this.host.UIElementAdded += Host_UIElementAdded; this.host.UIElementAdded += Host_UIElementAdded;
this.host.UIElementRemoved += Host_UIElementRemoved; this.host.UIElementRemoved += Host_UIElementRemoved;
} }
Dictionary<UIElement, MdiWindowRect> normalRect = new Dictionary<UIElement, MdiWindowRect>(); readonly Dictionary<UIElement, MdiWindowRect> normalRect = [];
readonly Panel host = new Panel { Size = SizeField.Fill }; readonly Panel host = new() { Size = SizeField.Fill };
readonly ListBox taskBar;
Collection<UIElement> TaskBarList { get => GetValue<Collection<UIElement>>(); set => SetValue(value); } Collection<UIElement> TaskBarList { get => GetValue<Collection<UIElement>>(); set => SetValue(value); }
public new UIElementCollection Children => host.Children; public new UIElementCollection Children => host.Children;
public MdiWindow SelectWindow { get => GetValue<MdiWindow>(); set => SetValue(value); } public MdiWindow SelectWindow { get => GetValue<MdiWindow>(); set => SetValue(value); }
[PropertyMetadata(TaskBarPlacement.Bottom)]
public TaskBarPlacement TaskBarPlacement { get => GetValue<TaskBarPlacement>(); set => SetValue(value); }
protected override void OnPropertyChanged(string propertyName, object oldValue, object newValue, PropertyMetadataAttribute propertyMetadata) protected override void OnPropertyChanged(string propertyName, object oldValue, object newValue, PropertyMetadataAttribute propertyMetadata)
{ {
if (propertyName == nameof(this.SelectWindow) && this.SelectWindow != null) if (propertyName == nameof(this.SelectWindow) && this.SelectWindow != null)
@ -60,6 +64,26 @@ namespace CPF.Toolkit.Controls
this.Topping(this.SelectWindow); this.Topping(this.SelectWindow);
this.SelectWindow.WindowState = this.normalRect[this.SelectWindow].OldState; 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); base.OnPropertyChanged(propertyName, oldValue, newValue, propertyMetadata);
} }
@ -86,8 +110,10 @@ namespace CPF.Toolkit.Controls
private void Host_UIElementRemoved(object sender, UIElementRemovedEventArgs e) private void Host_UIElementRemoved(object sender, UIElementRemovedEventArgs e)
{ {
e.Element.PropertyChanged -= Element_PropertyChanged; var view = e.Element as MdiWindow;
e.Element.PreviewMouseDown -= Element_PreviewMouseDown; view.PropertyChanged -= Element_PropertyChanged;
view.PreviewMouseDown -= Element_PreviewMouseDown;
view.Closing -= View_Closing;
this.TaskBarList.Remove(e.Element); this.TaskBarList.Remove(e.Element);
this.normalRect.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 }); this.normalRect.Add(e.Element, new MdiWindowRect { Left = 0, Top = 0, Height = 500, Width = 500 });
view.PropertyChanged += Element_PropertyChanged; view.PropertyChanged += Element_PropertyChanged;
view.PreviewMouseDown += Element_PreviewMouseDown; view.PreviewMouseDown += Element_PreviewMouseDown;
view.Closing += View_Closing;
this.TaskBarList.Add(view); this.TaskBarList.Add(view);
e.Element.ZIndex = this.host.Children.Max(x => x.ZIndex) + 1; e.Element.ZIndex = this.host.Children.Max(x => x.ZIndex) + 1;
this.Topping(view); 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) private void Element_PreviewMouseDown(object sender, Input.MouseButtonEventArgs e)
{ {
var ele = (MdiWindow)sender; var ele = (MdiWindow)sender;
@ -181,6 +239,7 @@ namespace CPF.Toolkit.Controls
public void Topping(MdiWindow ele) public void Topping(MdiWindow ele)
{ {
if (ele == null) return; if (ele == null) return;
ele.Focus();
var index = this.host.Children.Max(x => x.ZIndex); var index = this.host.Children.Max(x => x.ZIndex);
if (ele.ZIndex == index) if (ele.ZIndex == index)
{ {

View File

@ -8,10 +8,12 @@ using CPF.Platform;
using CPF.Shapes; using CPF.Shapes;
using CPF.Styling; using CPF.Styling;
using CPF.Svg; using CPF.Svg;
using CPF.Toolkit.Dialogs;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
@ -19,6 +21,10 @@ namespace CPF.Toolkit.Controls
{ {
public class MdiWindow : Control public class MdiWindow : Control
{ {
public MdiWindow()
{
this.Init();
}
public WindowState WindowState { get => GetValue<WindowState>(); set => SetValue(value); } public WindowState WindowState { get => GetValue<WindowState>(); set => SetValue(value); }
public UIElement Content { get => GetValue<UIElement>(); set => SetValue(value); } public UIElement Content { get => GetValue<UIElement>(); set => SetValue(value); }
@ -37,25 +43,43 @@ namespace CPF.Toolkit.Controls
[UIPropertyMetadata((byte)5, UIPropertyOptions.AffectsMeasure)] [UIPropertyMetadata((byte)5, UIPropertyOptions.AffectsMeasure)]
public byte ShadowBlur { get { return GetValue<byte>(); } set { SetValue(value); } } public byte ShadowBlur { get { return GetValue<byte>(); } set { SetValue(value); } }
[PropertyMetadata(true)]
public bool CanResize
{
get => GetValue<bool>();
set
{
SetValue(value);
if (!value) this.MaximizeBox = false;
}
}
public event EventHandler<ClosingEventArgs> Closing; public event EventHandler<ClosingEventArgs> Closing;
protected override void InitializeComponent()
void Init()
{ {
var bar = (ViewFill)"154,180,208"; this.Focusable = true;
var thubmEnabled = new BindingDescribe(this, nameof(WindowState), BindingMode.OneWay, b => ((WindowState)b) == WindowState.Normal); 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.Size = new SizeField(500, 500);
this.Background = null; this.Background = null;
this.MarginLeft = 0; this.MarginLeft = 0;
this.MarginTop = 0; this.MarginTop = 0;
this.MinWidth = 200;
this.MinHeight = 70;
this.ClipToBounds = true; this.ClipToBounds = true;
this.Children.Add(new Border this.Children.Add(new Border
{ {
Size = SizeField.Fill, Size = SizeField.Fill,
Background = "#fff", Background = "white",
BorderType = BorderType.BorderStroke, BorderType = BorderType.BorderStroke,
BorderStroke = new Stroke(0),
ShadowBlur = ShadowBlur, ShadowBlur = ShadowBlur,
ShadowColor = Color.FromRgba(0, 0, 0, 150), ShadowColor = Color.FromRgba(0, 0, 0, 150),
Child = new Decorator Child = new Decorator
@ -84,76 +108,140 @@ namespace CPF.Toolkit.Controls
{ {
Name = "top", Name = "top",
Size = "100%,5", Size = "100%,5",
Background = bar,
Cursor = Cursors.SizeNorthSouth, Cursor = Cursors.SizeNorthSouth,
Attacheds = { { Grid.ColumnSpan,3 } }, Attacheds = { { Grid.ColumnIndex,1 } },
[nameof(IsEnabled)] = thubmEnabled, [nameof(IsEnabled)] = dragEnabled,
Commands = [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) => this.MarginTop += args.VerticalChange;
{ this.Height -= args.VerticalChange;
var args = e as DragDeltaEventArgs;
if (this.Height.Value - args.VerticalChange > 0)
{
this.MarginTop += args.VerticalChange;
this.Height -= args.VerticalChange;
}
}
} }
}, }),
}, },
new Thumb new Thumb
{ {
Name = "left", Name = "left",
Size = "5,100%", Size = "5,100%",
Background = bar,
Cursor = Cursors.SizeWestEast, Cursor = Cursors.SizeWestEast,
IsEnabled = false, Attacheds = { { Grid.RowIndex,1 },{ Grid.RowSpan,2 } },
Attacheds = { { Grid.ColumnIndex,0 } ,{ Grid.RowSpan,4 } }, [nameof(IsEnabled)] = dragEnabled,
[nameof(IsEnabled)] = thubmEnabled, [nameof(Background)] = new BindingDescribe(this,nameof(IsFocused),BindingMode.OneWay ,x => ((bool)x) ? borderColor : lostFocusBorderColor),
Commands = [nameof(Thumb.DragDelta)] = new CommandDescribe((s,e) =>
{ {
var args = e as DragDeltaEventArgs;
if (this.Width.Value - args.HorizontalChange > 0)
{ {
nameof(Thumb.DragDelta),(s,e) => this.MarginLeft += args.HorizontalChange;
{ this.Width -= args.HorizontalChange;
var args = e as DragDeltaEventArgs;
if (this.Width.Value - args.HorizontalChange > 0)
{
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 new Thumb
{ {
Name = "right", Name = "right",
Size = "5,100%", Size = "5,100%",
Background = bar,
Cursor = Cursors.SizeWestEast, Cursor = Cursors.SizeWestEast,
MarginRight = 0, MarginRight = 0,
Attacheds = { { Grid.ColumnIndex,2 },{ Grid.RowSpan,4 } }, Attacheds = { { Grid.ColumnIndex,2 },{ Grid.RowIndex,1 },{ Grid.RowSpan,2 } },
[nameof(IsEnabled)] = thubmEnabled, [nameof(IsEnabled)] = dragEnabled,
Commands = { { nameof(Thumb.DragDelta),(s,e) => this.Width += (e as DragDeltaEventArgs).HorizontalChange } } [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 new Thumb
{ {
Name = "bottom", Name = "bottom",
Size = "100%,5", Size = "100%,5",
Background = bar,
Cursor = Cursors.SizeNorthSouth, Cursor = Cursors.SizeNorthSouth,
Attacheds = { { Grid.RowIndex,3 },{ Grid.ColumnSpan,3 } }, Attacheds = { { Grid.RowIndex,3 },{ Grid.ColumnIndex,1 } },
[nameof(IsEnabled)] = thubmEnabled, [nameof(IsEnabled)] = dragEnabled,
Commands = { { nameof(Thumb.DragDelta),(s,e) => this.Height += (e as DragDeltaEventArgs).VerticalChange } } [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 new Thumb
{ {
Name = "caption", Name = "caption",
Attacheds = { { Grid.RowIndex,1 },{ Grid.ColumnIndex,1 } }, Attacheds = { { Grid.RowIndex,1 },{ Grid.ColumnIndex,1 } },
Size = SizeField.Fill, Size = SizeField.Fill,
Background = bar,
Child = new Panel Child = new Panel
{ {
Size = SizeField.Fill, Size = SizeField.Fill,
@ -193,8 +281,8 @@ namespace CPF.Toolkit.Controls
IsAntiAlias = true, IsAntiAlias = true,
StrokeFill = "black" StrokeFill = "black"
}, },
[nameof(Visibility)] = new BindingDescribe(this,nameof(MinimizeBox),BindingMode.OneWay,a=>(bool)a?Visibility.Visible: Visibility.Collapsed), [nameof(Visibility)] = new BindingDescribe(this,nameof(MinimizeBox),BindingMode.OneWay,x=>(bool)x?Visibility.Visible: Visibility.Collapsed),
Commands = { { nameof(Button.Click),(s,e) => this.WindowState = WindowState.Minimized } }, [nameof(Button.Click)] = new CommandDescribe((s,e) => this.WindowState = WindowState.Minimized)
}, },
new Panel new Panel
{ {
@ -212,12 +300,13 @@ namespace CPF.Toolkit.Controls
MarginTop = 5, MarginTop = 5,
StrokeStyle = "2", StrokeStyle = "2",
}, },
Commands = { { nameof(Button.Click),(s,e) => this.WindowState = WindowState.Maximized } }, [nameof(Button.Click)] = new CommandDescribe((s, e) => this.WindowState = WindowState.Maximized),
[nameof(Visibility)] = new BindingDescribe(this, [nameof(Visibility)] =
nameof(WindowState), new BindingDescribe(
BindingMode.OneWay, this,
a => ((WindowState)a).Or(WindowState.Maximized,WindowState.FullScreen) nameof(WindowState),
? Visibility.Collapsed : Visibility.Visible), BindingMode.OneWay,
x => ((WindowState)x).Or(WindowState.Maximized,WindowState.FullScreen) ? Visibility.Collapsed : Visibility.Visible),
}, },
new SystemButton new SystemButton
{ {
@ -252,13 +341,13 @@ namespace CPF.Toolkit.Controls
} }
} }
}, },
Commands = { { nameof(Button.Click),(s,e) => this.WindowState = WindowState.Normal } }, [nameof(Button.Click)] = new CommandDescribe((s, e) => this.WindowState = WindowState.Normal),
[nameof(Visibility)] = new BindingDescribe(this, [nameof(Visibility)] =
nameof(WindowState), new BindingDescribe(
BindingMode.OneWay, this,
a => ((WindowState)a).Or( WindowState.Normal, WindowState.Minimized) nameof(WindowState),
? Visibility.Collapsed : BindingMode.OneWay,
Visibility.Visible) x => ((WindowState)x).Or(WindowState.Normal,WindowState.Minimized)? Visibility.Collapsed : Visibility.Visible)
} }
} }
}, },
@ -291,79 +380,98 @@ namespace CPF.Toolkit.Controls
} }
} }
}, },
Commands = [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)
{
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)
} }
} }
}, },
}, },
}, },
Commands = [nameof(Thumb.DragDelta)] = new CommandDescribe((ss,ee)=>
{ {
if (this.WindowState.Or(WindowState.Normal))
{ {
nameof(Thumb.DragDelta), var arge = ee as DragDeltaEventArgs;
(s,e) => this.MarginLeft += arge.HorizontalChange;
{ this.MarginTop += arge.VerticalChange;
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;
}
})
} }
}, }),
[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 new Decorator
{ {
Attacheds = { { Grid.RowIndex,2 } ,{ Grid.ColumnIndex,1 } }, Attacheds = { { Grid.RowIndex,2 } ,{ Grid.ColumnIndex,1 } },
Size = SizeField.Fill, Size = SizeField.Fill,
Child = this.Content, [nameof(Decorator.Child)] = new BindingDescribe(this,nameof(Content))
}, },
} }
}, },
}, },
[nameof(Border.ShadowBlur)] = new BindingDescribe(this, [nameof(ShadowBlur)] = new BindingDescribe(this, nameof(WindowState), BindingMode.OneWay, x => ((WindowState)x).Or(WindowState.Maximized, WindowState.FullScreen) ? 0 : ShadowBlur),
nameof(WindowState), [nameof(ShadowBlur)] = new BindingDescribe(this, nameof(IsFocused), BindingMode.OneWay, x => ((bool)x) ? ShadowBlur : 0),
BindingMode.OneWay, [nameof(BorderStroke)] = new BindingDescribe(this, nameof(IsFocused), BindingMode.OneWay, x => ((bool)x) ? "0" : "1"),
a => ((WindowState)a).Or(WindowState.Maximized, WindowState.FullScreen) ? 0 : ShadowBlur), [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);
} }
} }
} }

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace CPF.Toolkit.Controls
{
public enum TaskBarPlacement
{
Top,
Bottom,
}
}

View File

@ -8,7 +8,7 @@ namespace CPF.Toolkit.Dialogs
{ {
internal interface IClosable internal interface IClosable
{ {
event EventHandler<object> Closable; event EventHandler<ClosingEventArgs> Closable;
void OnClosable(object sender, ClosingEventArgs e); void OnClosable(object sender, ClosingEventArgs e);
} }
} }

View File

@ -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);
};
}
}
}

View File

@ -24,12 +24,8 @@ namespace CPF.Toolkit
{ {
if (view.DataContext is IClosable closable) if (view.DataContext is IClosable closable)
{ {
closable.Closable += (ss, dialogResult) => closable.Closable += (ss, ee) =>
{ {
if (view.IsDialogMode == true)
{
view.DialogResult = dialogResult;
}
view.Close(); view.Close();
}; };
} }
@ -39,40 +35,9 @@ namespace CPF.Toolkit
} }
if (view.DataContext is ILoading loading) if (view.DataContext is ILoading loading)
{ {
loading.ShowLoadingFunc += async (message, task) => loading.CreateLoading(view);
{
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);
};
} }
} }
} }
private static void View_Closing(object sender, ClosingEventArgs e) private static void View_Closing(object sender, ClosingEventArgs e)

View File

@ -9,10 +9,10 @@ namespace CPF.Toolkit
{ {
public class ViewModelBase : ObservableObject, IClosable, IDialog, ILoading public class ViewModelBase : ObservableObject, IClosable, IDialog, ILoading
{ {
event EventHandler<object> _close; event EventHandler<ClosingEventArgs> _close;
event Func<string, Task, Task<object>> _showLoadingFunc; event Func<string, Task, Task<object>> _showLoadingFunc;
event Func<string, Task, Task> _showLading; event Func<string, Task, Task> _showLading;
event EventHandler<object> IClosable.Closable { add => this._close += value; remove => this._close -= value; } event EventHandler<ClosingEventArgs> IClosable.Closable { add => this._close += value; remove => this._close -= value; }
event Func<string, Task, Task<object>> ILoading.ShowLoadingFunc { add => this._showLoadingFunc += value; remove => this._showLoadingFunc -= value; } event Func<string, Task, Task<object>> ILoading.ShowLoadingFunc { add => this._showLoadingFunc += value; remove => this._showLoadingFunc -= value; }
event Func<string, Task, Task> ILoading.ShowLoading { add => this._showLading += value; remove => this._showLading -= value; } event Func<string, Task, Task> ILoading.ShowLoading { add => this._showLading += value; remove => this._showLading -= value; }
@ -20,10 +20,10 @@ namespace CPF.Toolkit
public IDialogService Dialog { get; set; } public IDialogService Dialog { get; set; }
protected void Close(object dialogResult = null) protected void Close()
{ {
if (this._close == null) throw new ArgumentNullException(); if (this._close == null) throw new ArgumentNullException();
this._close.Invoke(this, dialogResult); this._close.Invoke(this, new ClosingEventArgs());
} }
protected virtual void OnClose(ClosingEventArgs e) { } protected virtual void OnClose(ClosingEventArgs e) { }

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Text; using System.Text;
using System.ComponentModel; using System.ComponentModel;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Threading.Tasks;
namespace CPF namespace CPF
{ {
@ -17,7 +18,7 @@ namespace CPF
{ {
PropertyName = sourceProperty; PropertyName = sourceProperty;
} }
public BindingDescribe(string sourceProperty, BindingMode binding) public BindingDescribe(string sourceProperty, BindingMode binding)
{ {
PropertyName = sourceProperty; PropertyName = sourceProperty;
@ -401,6 +402,7 @@ namespace CPF
public class CommandDescribe public class CommandDescribe
{ {
public Action<CpfObject, object> Action { get; set; } public Action<CpfObject, object> Action { get; set; }
public Func<CpfObject, object, Task> AsyncAction { get; set; }
public string MethodName { get; set; } public string MethodName { get; set; }
public object[] Parameters { get; set; } public object[] Parameters { get; set; }
@ -416,6 +418,11 @@ namespace CPF
{ {
Action = command; Action = command;
} }
public CommandDescribe(Func<CpfObject, object, Task> command)
{
this.AsyncAction = command;
}
/// <summary> /// <summary>
/// 定义个命令绑定 /// 定义个命令绑定
/// </summary> /// </summary>

View File

@ -194,6 +194,10 @@ namespace CPF
{ {
if (value.Command != null) if (value.Command != null)
{ {
if (value.Command.AsyncAction != null)
{
Commands.Add(propertyName, value.Command.AsyncAction);
}
if (value.Command.Action != null) if (value.Command.Action != null)
{ {
Commands.Add(propertyName, value.Command.Action); Commands.Add(propertyName, value.Command.Action);