viewmodel中增加close方法与onclose用于拦截关闭事件

This commit is contained in:
Sakura 2023-11-22 21:02:42 +08:00
parent f673ced43a
commit 2cd339388f
11 changed files with 150 additions and 58 deletions

View File

@ -28,7 +28,6 @@ namespace CPF.Toolkit.Demo
Background = null;
var vm = new MainViewModel();
this.DataContext = this.CommandContext = vm;
vm.Dialog = new DialogService(this);
Children.Add(new WindowFrame(this, new WrapPanel
{
@ -61,8 +60,13 @@ namespace CPF.Toolkit.Demo
Content = "Warn",
Commands = { { nameof(Button.Click),(s,e) => vm.Dialog.Warn("这是一条测试消息") } }
},
new Button
{
Content = "关闭窗体",
Commands = { { nameof(Button.Click),(s,e) => vm.Test() } }
},
}
})) ;
}));
}
}
}

View File

@ -1,4 +1,5 @@
using System;
using CPF.Controls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -8,7 +9,20 @@ 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);
}
}
}

View File

@ -1,5 +1,7 @@
using CPF.Platform;
using CPF.Controls;
using CPF.Platform;
using CPF.Skia;
using CPF.Toolkit.Dialogs;
using CPF.Windows;
namespace CPF.Toolkit.Demo
@ -14,7 +16,8 @@ namespace CPF.Toolkit.Demo
, (OperatingSystemType.OSX, new CPF.Mac.MacPlatform(), new SkiaDrawingFactory { UseGPU = false })
, (OperatingSystemType.Linux, new CPF.Linux.LinuxPlatform(), new SkiaDrawingFactory { UseGPU = false })
);
Application.Run(new MainView { });
Application.Run(ViewManager.View<MainView>());
}
}
}

View File

@ -16,17 +16,6 @@ namespace CPF.Toolkit.Dialogs
this.window = window;
this.content = content;
}
/// <summary>
/// 是否显示最大化还原按钮
/// </summary>
public bool MaximizeBox { get { return GetValue<bool>(); } set { SetValue(value); } }
/// <summary>
/// 是否显示最小化
/// </summary>
[PropertyMetadata(true)]
public bool MinimizeBox { get { return GetValue<bool>(); } set { SetValue(value); } }
IWindow window;
/// <summary>
/// 关联的窗体
@ -47,15 +36,6 @@ namespace CPF.Toolkit.Dialogs
get { return content; }
}
IEnumerable<UIElement> systemButtons;
/// <summary>
/// 系统按钮集合
/// </summary>
[NotCpfProperty]
public IEnumerable<UIElement> SystemButtons
{
get { return systemButtons; }
}
/// <summary>
/// 阴影宽度
@ -79,7 +59,6 @@ namespace CPF.Toolkit.Dialogs
protected override void InitializeComponent()
{
ViewFill color = "black";
ViewFill hoverColor = "255,255,255,40";
Width = "100%";
@ -155,10 +134,6 @@ namespace CPF.Toolkit.Dialogs
nameof(MouseDown),
nameof(IWindow.DragMove),
Window
},
{
nameof(DoubleClick),
(s,e)=> DoubleClickTitle()
}
},
Children =
@ -292,19 +267,5 @@ namespace CPF.Toolkit.Dialogs
grid.Children.Add(Content, 0, 1);
}
}
protected void DoubleClickTitle()
{
if (MaximizeBox)
{
this.Delay(TimeSpan.FromMilliseconds(100), () =>
{
if (Window.WindowState == WindowState.Normal)
{ Window.WindowState = WindowState.Maximized; }
else if (Window.WindowState == WindowState.Maximized)
{ Window.WindowState = WindowState.Normal; }
});
}
}
}
}

View File

@ -3,6 +3,7 @@ using CPF.Animation;
using CPF.Charts;
using CPF.Controls;
using CPF.Drawing;
using CPF.Input;
using CPF.Shapes;
using CPF.Styling;
using CPF.Svg;
@ -126,11 +127,7 @@ namespace CPF.Toolkit.Dialogs
}).ToList().ForEach(c =>
{
p.Children.Add(c);
c.Click += C_Click;
if (c.Content.ToString() == this.DefaultButton)
{
c.Focus();
}
c.Click += Button_Click;
});
textBox.TextChanged += TextBox_TextChanged;
}
@ -150,9 +147,22 @@ namespace CPF.Toolkit.Dialogs
}
}
private void C_Click(object sender, RoutedEventArgs e)
private void Button_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = (sender as Button).Content;
this.Close();
}
protected override void OnKeyUp(KeyEventArgs e)
{
if (e.Key.Or(Keys.Enter, Keys.Space))
{
var buttons = this.Find<Button>();
var btn = buttons.FirstOrDefault(x => x.IsFocused) ?? buttons.FirstOrDefault(x => x.Content?.ToString() == this.DefaultButton);
this.DialogResult = btn.Content.ToString();
e.Handled = true;
}
base.OnKeyUp(e);
}
}
}

View File

@ -0,0 +1,14 @@
using CPF.Controls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
namespace CPF.Toolkit.Dialogs
{
internal interface IClosable
{
event EventHandler<bool?> Closable;
void OnClosable(object sender, ClosingEventArgs e);
}
}

View File

@ -1,10 +1,16 @@
using CPF.Controls;
using CPF.Platform;
using System;
using System.Collections.Generic;
using System.Text;
namespace CPF.Toolkit.Dialogs
{
public interface IDialog
{
IDialogService Dialog { get; set; }
}
public interface IDialogService
{
string Alert(string text, string title, DialogType dialogType, string defaultButton, params string[] buttons);
@ -26,9 +32,8 @@ namespace CPF.Toolkit.Dialogs
public string Alert(string text, string title, DialogType dialogType, string defaultButton, params string[] buttons)
{
var view = new DialogView(text, title, dialogType, defaultButton, buttons);
view.MarginLeft = this.owner.MarginLeft.Value - this.owner.Width.Value / 2;
view.MarginTop = this.owner.MarginTop.Value - this.owner.Height.Value / 2;
return view.ShowDialogSync(this.owner)?.ToString();
var result = view.ShowDialogSync(owner);
return result?.ToString();
}
public void Alert(string text)

View File

@ -0,0 +1,48 @@
using CPF.Controls;
using CPF.Toolkit.Dialogs;
using System;
using System.Collections.Generic;
using System.Text;
namespace CPF.Toolkit
{
public static class ViewManager
{
public static T View<T>(params object[] arges) where T : Window
{
var view = Activator.CreateInstance(typeof(T), arges) as T;
view.Initialized += View_Initialized;
view.Closing += View_Closing;
return view;
}
private static void View_Closing(object sender, ClosingEventArgs e)
{
var view = sender as Window;
if (view.DataContext is IClosable closable)
{
closable.OnClosable(sender, e);
}
}
private static void View_Initialized(object sender, EventArgs e)
{
var view = sender as Window;
if (view.DataContext is IClosable closable)
{
closable.Closable += (ss, dialogResult) =>
{
if (view.IsDialogMode == true)
{
view.DialogResult = dialogResult;
}
view.Close();
};
}
if (view.DataContext is IDialog dialog)
{
dialog.Dialog = new DialogService(view);
}
}
}
}

View File

@ -1,12 +1,30 @@
using CPF.Toolkit.Dialogs;
using CPF.Controls;
using CPF.Toolkit.Dialogs;
using System;
using System.Collections.Generic;
using System.Text;
namespace CPF.Toolkit
{
public class ViewModelBase : ObservableObject
public class ViewModelBase : ObservableObject, IClosable, IDialog
{
event EventHandler<bool?> _close;
public IDialogService Dialog { get; set; }
event EventHandler<bool?> IClosable.Closable { add => this._close += value; remove => this._close -= value; }
protected void Close(bool? dialogResult = null)
{
if (this._close == null)
{
throw new ArgumentNullException();
}
this._close.Invoke(this, dialogResult);
}
protected virtual void OnClose(ClosingEventArgs e) { }
void IClosable.OnClosable(object sender, ClosingEventArgs e) => this.OnClose(e);
}
}

View File

@ -27,7 +27,7 @@ namespace CPF.Controls
public static IEnumerable<Window> Windows { get { return windows; } }
IWindowImpl windowImpl;
bool? isDialog;
public event EventHandler Closed
{
add { AddHandler(value); }
@ -314,8 +314,11 @@ namespace CPF.Controls
}
}
public bool? IsDialogMode => this.isDialog;
void SetDialog(bool enable, Window child)
{
this.isDialog = true;
if (dialogChildren == null)
{
dialogChildren = new HashSet<Window>();

View File

@ -28,7 +28,7 @@ namespace CPF
/// <param name="o"></param>
/// <param name="v"></param>
/// <returns></returns>
public static T Assign<T>(this T o,out T v)
public static T Assign<T>(this T o, out T v)
{
v = o;
return o;
@ -652,6 +652,18 @@ namespace CPF
}
return element;
}
public static bool Or<T>(this T obj, params T[] ps)
{
foreach (var item in ps)
{
if (obj.Equals(item))
{
return true;
}
}
return false;
}
}
class Enumerable : IList