Merge branch 'main' of github.com:KJD2025/29WxOrder
This commit is contained in:
commit
5fb42e4d34
15 files changed
+1055
-21
No files matched your search
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Prism.Services.Dialogs;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Remoting.Contexts;
|
||||
@@ -14,7 +15,7 @@ namespace _29WxOrderWpf.Common
|
||||
/// <summary>
|
||||
/// DialogWindow.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class DialogWindow : Window
|
||||
public partial class DialogWindow : Window, IDialogWindow
|
||||
{
|
||||
private readonly Style dialogWindowStyle;
|
||||
private bool isConstructorSuccessful = false;
|
||||
@@ -101,6 +102,8 @@ namespace _29WxOrderWpf.Common
|
||||
private const int GWL_STYLE = -16;
|
||||
private const int WS_MINIMIZEBOX = 0x00020000;
|
||||
|
||||
public IDialogResult Result { get; set; }
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
namespace Prism.Services.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// The result of the dialog.
|
||||
/// </summary>
|
||||
public enum ButtonResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Abort.
|
||||
/// </summary>
|
||||
Abort = 3,
|
||||
/// <summary>
|
||||
/// Cancel.
|
||||
/// </summary>
|
||||
Cancel = 2,
|
||||
/// <summary>
|
||||
/// Ignore.
|
||||
/// </summary>
|
||||
Ignore = 5,
|
||||
/// <summary>
|
||||
/// No.
|
||||
/// </summary>
|
||||
No = 7,
|
||||
/// <summary>
|
||||
/// No result returned.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
/// <summary>
|
||||
/// OK.
|
||||
/// </summary>
|
||||
OK = 1,
|
||||
/// <summary>
|
||||
/// Retry.
|
||||
/// </summary>
|
||||
Retry = 4,
|
||||
/// <summary>
|
||||
/// Yes.
|
||||
/// </summary>
|
||||
Yes = 6
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
#if HAS_UWP
|
||||
using Windows.UI.Xaml;
|
||||
#elif HAS_WINUI
|
||||
using Microsoft.UI.Xaml;
|
||||
#else
|
||||
using System.Windows;
|
||||
#endif
|
||||
|
||||
namespace Prism.Services.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains <see cref="IDialogWindow"/> attached properties.
|
||||
/// </summary>
|
||||
public class Dialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies the WindowStyle attached property.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This attached property is used to specify the style of a <see cref="IDialogWindow"/>.
|
||||
/// </remarks>
|
||||
public static readonly DependencyProperty WindowStyleProperty =
|
||||
DependencyProperty.RegisterAttached("WindowStyle", typeof(Style), typeof(Dialog), new PropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value for the <see cref="WindowStyleProperty"/> attached property.
|
||||
/// </summary>
|
||||
/// <param name="obj">The target element.</param>
|
||||
/// <returns>The <see cref="WindowStyleProperty"/> attached to the <paramref name="obj"/> element.</returns>
|
||||
public static Style GetWindowStyle(DependencyObject obj)
|
||||
{
|
||||
return (Style)obj.GetValue(WindowStyleProperty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="WindowStyleProperty"/> attached property.
|
||||
/// </summary>
|
||||
/// <param name="obj">The target element.</param>
|
||||
/// <param name="value">The Style to attach.</param>
|
||||
public static void SetWindowStyle(DependencyObject obj, Style value)
|
||||
{
|
||||
obj.SetValue(WindowStyleProperty, value);
|
||||
}
|
||||
|
||||
#if !HAS_UWP && !HAS_WINUI
|
||||
/// <summary>
|
||||
/// Identifies the WindowStartupLocation attached property.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This attached property is used to specify the startup location of a <see cref="IDialogWindow"/>.
|
||||
/// </remarks>
|
||||
public static readonly DependencyProperty WindowStartupLocationProperty =
|
||||
DependencyProperty.RegisterAttached("WindowStartupLocation", typeof(WindowStartupLocation), typeof(Dialog), new UIPropertyMetadata(OnWindowStartupLocationChanged));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value for the <see cref="WindowStartupLocationProperty"/> attached property.
|
||||
/// </summary>
|
||||
/// <param name="obj">The target element.</param>
|
||||
/// <returns>The <see cref="WindowStartupLocationProperty"/> attached to the <paramref name="obj"/> element.</returns>
|
||||
public static WindowStartupLocation GetWindowStartupLocation(DependencyObject obj)
|
||||
{
|
||||
return (WindowStartupLocation)obj.GetValue(WindowStartupLocationProperty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="WindowStartupLocationProperty"/> attached property.
|
||||
/// </summary>
|
||||
/// <param name="obj">The target element.</param>
|
||||
/// <param name="value">The WindowStartupLocation to attach.</param>
|
||||
public static void SetWindowStartupLocation(DependencyObject obj, WindowStartupLocation value)
|
||||
{
|
||||
obj.SetValue(WindowStartupLocationProperty, value);
|
||||
}
|
||||
|
||||
private static void OnWindowStartupLocationChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (sender is Window window)
|
||||
window.WindowStartupLocation = (WindowStartupLocation)e.NewValue;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using Prism.Common;
|
||||
|
||||
namespace Prism.Services.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents Dialog parameters.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class can be used to to pass object parameters during the showing and closing of Dialogs.
|
||||
/// </remarks>
|
||||
public class DialogParameters : ParametersBase, IDialogParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DialogParameters"/> class.
|
||||
/// </summary>
|
||||
public DialogParameters() : base() { }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a list of parameters.
|
||||
/// </summary>
|
||||
/// <param name="query">Query string to be parsed.</param>
|
||||
public DialogParameters(string query) : base(query) { }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
namespace Prism.Services.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// An <see cref="IDialogResult"/> that contains <see cref="IDialogParameters"/> from the dialog
|
||||
/// and the <see cref="ButtonResult"/> of the dialog.
|
||||
/// </summary>
|
||||
public class DialogResult : IDialogResult
|
||||
{
|
||||
/// <summary>
|
||||
/// The parameters from the dialog.
|
||||
/// </summary>
|
||||
public IDialogParameters Parameters { get; private set; } = new DialogParameters();
|
||||
|
||||
/// <summary>
|
||||
/// The result of the dialog.
|
||||
/// </summary>
|
||||
public ButtonResult Result { get; private set; } = ButtonResult.None;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DialogResult"/> class.
|
||||
/// </summary>
|
||||
public DialogResult() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DialogResult"/> class.
|
||||
/// </summary>
|
||||
/// <param name="result">The result of the dialog.</param>
|
||||
public DialogResult(ButtonResult result)
|
||||
{
|
||||
Result = result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DialogResult"/> class.
|
||||
/// </summary>
|
||||
/// <param name="result">The result of the dialog.</param>
|
||||
/// <param name="parameters">The parameters from the dialog.</param>
|
||||
public DialogResult(ButtonResult result, IDialogParameters parameters)
|
||||
{
|
||||
Result = result;
|
||||
Parameters = parameters;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
using _29WxOrderWpf.Common;
|
||||
using Prism.Common;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
|
||||
namespace Prism.Services.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// 静态弹窗服务:不依赖容器,直接传入 View 实例弹出。
|
||||
/// ViewModel 需实现 IDialogAware。
|
||||
/// </summary>
|
||||
public static class DialogService
|
||||
{
|
||||
// ========== 对外接口 ==========
|
||||
|
||||
/// <summary>非模态弹出</summary>
|
||||
public static void Show(FrameworkElement view,
|
||||
IDialogParameters parameters = null,
|
||||
Action<IDialogResult> callback = null,
|
||||
IDialogWindow window = null)
|
||||
{
|
||||
ShowInternal(view, parameters, callback, false, window);
|
||||
}
|
||||
|
||||
/// <summary>模态弹出</summary>
|
||||
public static void ShowDialog(FrameworkElement view,
|
||||
IDialogParameters parameters = null,
|
||||
Action<IDialogResult> callback = null,
|
||||
IDialogWindow window = null)
|
||||
{
|
||||
ShowInternal(view, parameters, callback, true, window);
|
||||
}
|
||||
|
||||
// ========== 内部实现 ==========
|
||||
|
||||
private static void ShowInternal(FrameworkElement view,
|
||||
IDialogParameters parameters,
|
||||
Action<IDialogResult> callback,
|
||||
bool isModal,
|
||||
IDialogWindow window)
|
||||
{
|
||||
if (view == null) throw new ArgumentNullException(nameof(view));
|
||||
if (parameters == null) parameters = new DialogParameters();
|
||||
|
||||
// 1. 创建(或使用传入的)DialogWindow
|
||||
var dialogWindow = window ?? new DialogWindow();
|
||||
|
||||
// 2. 绑定事件(关闭、回调等)
|
||||
ConfigureDialogWindowEvents(dialogWindow, callback);
|
||||
|
||||
// 3. 配置内容(View + ViewModel)
|
||||
ConfigureDialogWindowContent(view, dialogWindow, parameters);
|
||||
|
||||
// 4. 弹出
|
||||
ShowDialogWindow(dialogWindow, isModal);
|
||||
}
|
||||
|
||||
private static void ShowDialogWindow(IDialogWindow dialogWindow, bool isModal)
|
||||
{
|
||||
if (isModal)
|
||||
dialogWindow.ShowDialog();
|
||||
else
|
||||
dialogWindow.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 把 View 挂到 DialogWindow 上,并触发 OnDialogOpened。
|
||||
/// </summary>
|
||||
private static void ConfigureDialogWindowContent(FrameworkElement dialogContent,
|
||||
IDialogWindow window,
|
||||
IDialogParameters parameters)
|
||||
{
|
||||
// 不再自动绑 ViewModel,DataContext 由 View 自己负责
|
||||
if (!(dialogContent.DataContext is IDialogAware viewModel))
|
||||
throw new NullReferenceException("A dialog's ViewModel must implement the IDialogAware interface");
|
||||
|
||||
ConfigureDialogWindowProperties(window, dialogContent, viewModel);
|
||||
|
||||
// 直接触发 OnDialogOpened(替代 MvvmHelpers.ViewAndViewModelAction)
|
||||
viewModel.OnDialogOpened(parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定 DialogWindow 的生命周期事件。
|
||||
/// </summary>
|
||||
private static void ConfigureDialogWindowEvents(IDialogWindow dialogWindow, Action<IDialogResult> callback)
|
||||
{
|
||||
Action<IDialogResult> requestCloseHandler = null;
|
||||
requestCloseHandler = (o) =>
|
||||
{
|
||||
dialogWindow.Result = o;
|
||||
dialogWindow.Close();
|
||||
};
|
||||
|
||||
RoutedEventHandler loadedHandler = null;
|
||||
loadedHandler = (o, e) =>
|
||||
{
|
||||
dialogWindow.Loaded -= loadedHandler;
|
||||
GetDialogViewModel(dialogWindow).RequestClose += requestCloseHandler;
|
||||
};
|
||||
dialogWindow.Loaded += loadedHandler;
|
||||
|
||||
CancelEventHandler closingHandler = null;
|
||||
closingHandler = (o, e) =>
|
||||
{
|
||||
if (!GetDialogViewModel(dialogWindow).CanCloseDialog())
|
||||
e.Cancel = true;
|
||||
};
|
||||
dialogWindow.Closing += closingHandler;
|
||||
|
||||
EventHandler closedHandler = null;
|
||||
closedHandler = (o, e) =>
|
||||
{
|
||||
dialogWindow.Closed -= closedHandler;
|
||||
dialogWindow.Closing -= closingHandler;
|
||||
GetDialogViewModel(dialogWindow).RequestClose -= requestCloseHandler;
|
||||
GetDialogViewModel(dialogWindow).OnDialogClosed();
|
||||
|
||||
|
||||
if (dialogWindow.Result == null)
|
||||
dialogWindow.Result = new DialogResult();
|
||||
|
||||
callback?.Invoke(dialogWindow.Result);
|
||||
|
||||
dialogWindow.DataContext = null;
|
||||
dialogWindow.Content = null;
|
||||
};
|
||||
dialogWindow.Closed += closedHandler;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置 DialogWindow 的 Style / Content / DataContext / Owner。
|
||||
/// </summary>
|
||||
private static void ConfigureDialogWindowProperties(IDialogWindow window,
|
||||
FrameworkElement dialogContent,
|
||||
IDialogAware viewModel)
|
||||
{
|
||||
var windowStyle = Dialog.GetWindowStyle(dialogContent);
|
||||
if (windowStyle != null)
|
||||
window.Style = windowStyle;
|
||||
|
||||
window.Content = dialogContent;
|
||||
window.DataContext = viewModel; // 宿主窗口和对话框共享同一个 DataContext
|
||||
|
||||
if (window.Owner == null)
|
||||
window.Owner = Application.Current?.Windows
|
||||
.OfType<Window>()
|
||||
.FirstOrDefault(x => x.IsActive);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 window.Content 或 window.DataContext 里拿 IDialogAware。
|
||||
/// 替代 Prism 的 dialogWindow.GetDialogViewModel() 扩展方法。
|
||||
/// </summary>
|
||||
private static IDialogAware GetDialogViewModel(IDialogWindow window)
|
||||
{
|
||||
if (window.Content is FrameworkElement fe)
|
||||
{
|
||||
if (fe is IDialogAware aware) return aware;
|
||||
if (fe.DataContext is IDialogAware vm) return vm;
|
||||
}
|
||||
|
||||
if (window.DataContext is IDialogAware wvm) return wvm;
|
||||
|
||||
throw new NullReferenceException("A dialog's ViewModel must implement the IDialogAware interface");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
|
||||
namespace Prism.Services.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface that provides dialog functions and events to ViewModels.
|
||||
/// </summary>
|
||||
public interface IDialogAware
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines if the dialog can be closed.
|
||||
/// </summary>
|
||||
/// <returns>If <c>true</c> the dialog can be closed. If <c>false</c> the dialog will not close.</returns>
|
||||
bool CanCloseDialog();
|
||||
|
||||
/// <summary>
|
||||
/// Called when the dialog is closed.
|
||||
/// </summary>
|
||||
void OnDialogClosed();
|
||||
|
||||
/// <summary>
|
||||
/// Called when the dialog is opened.
|
||||
/// </summary>
|
||||
/// <param name="parameters">The parameters passed to the dialog.</param>
|
||||
void OnDialogOpened(IDialogParameters parameters);
|
||||
|
||||
/// <summary>
|
||||
/// The title of the dialog that will show in the window title bar.
|
||||
/// </summary>
|
||||
string Title { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Instructs the <see cref="IDialogWindow"/> to close the dialog.
|
||||
/// </summary>
|
||||
event Action<IDialogResult> RequestClose;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Prism.Services.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents Dialog parameters.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A class that implements this interface can be used to pass
|
||||
/// object parameters during the showing and closing of Dialogs.
|
||||
/// </remarks>
|
||||
public interface IDialogParameters
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the key and value to the collection.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to reference this parameter value in the collection.</param>
|
||||
/// <param name="value">The parameter value to store.</param>
|
||||
void Add(string key, object value);
|
||||
|
||||
/// <summary>
|
||||
/// Checks the collection for the presence of a key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to check.</param>
|
||||
/// <returns><c>true</c> if key exists; <c>false</c> otherwise.</returns>
|
||||
bool ContainsKey(string key);
|
||||
|
||||
/// <summary>
|
||||
/// The number of parameters in the collection.
|
||||
/// </summary>
|
||||
int Count { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The keys in the collection.
|
||||
/// </summary>
|
||||
IEnumerable<string> Keys { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter value referenced by a key.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object to be returned.</typeparam>
|
||||
/// <param name="key">The key of the parameter value to be returned.</param>
|
||||
/// <returns>The matching parameter of type <typeparamref name="T"/>.</returns>
|
||||
T GetValue<T>(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets all parameter values referenced by a key.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object to be returned.</typeparam>
|
||||
/// <param name="key">The key of the parameter values to be returned.</param>
|
||||
///<returns>All matching parameter values of type <typeparamref name="T"/>.</returns>
|
||||
IEnumerable<T> GetValues<T>(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter value if the referenced key exists.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object to be returned.</typeparam>
|
||||
/// <param name="key">The key of the parameter value to be returned.</param>
|
||||
/// <param name="value">The matching parameter of type <typeparamref name="T"/> if the key exists.</param>
|
||||
/// <returns><c>true</c> if the parameter exists; <c>false</c> otherwise.</returns>
|
||||
bool TryGetValue<T>(string key, out T value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
namespace Prism.Services.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains <see cref="IDialogParameters"/> from the dialog
|
||||
/// and the <see cref="ButtonResult"/> of the dialog.
|
||||
/// </summary>
|
||||
public interface IDialogResult
|
||||
{
|
||||
/// <summary>
|
||||
/// The parameters from the dialog.
|
||||
/// </summary>
|
||||
IDialogParameters Parameters { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The result of the dialog.
|
||||
/// </summary>
|
||||
ButtonResult Result { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
|
||||
namespace Prism.Services.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for a dialog hosting window.
|
||||
/// </summary>
|
||||
public interface IDialogWindow
|
||||
{
|
||||
/// <summary>
|
||||
/// Dialog content.
|
||||
/// </summary>
|
||||
object Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Close the window.
|
||||
/// </summary>
|
||||
void Close();
|
||||
|
||||
/// <summary>
|
||||
/// The window's owner.
|
||||
/// </summary>
|
||||
Window Owner { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Show a non-modal dialog.
|
||||
/// </summary>
|
||||
void Show();
|
||||
|
||||
/// <summary>
|
||||
/// Show a modal dialog.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool? ShowDialog();
|
||||
|
||||
/// <summary>
|
||||
/// The data context of the window.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The data context must implement <see cref="IDialogAware"/>.
|
||||
/// </remarks>
|
||||
object DataContext { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the window is loaded.
|
||||
/// </summary>
|
||||
event RoutedEventHandler Loaded;
|
||||
|
||||
/// <summary>
|
||||
/// Called when the window is closed.
|
||||
/// </summary>
|
||||
event EventHandler Closed;
|
||||
|
||||
/// <summary>
|
||||
/// Called when the window is closing.
|
||||
/// </summary>
|
||||
event CancelEventHandler Closing;
|
||||
|
||||
/// <summary>
|
||||
/// The result of the dialog.
|
||||
/// </summary>
|
||||
IDialogResult Result { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The window style.
|
||||
/// </summary>
|
||||
Style Style { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Prism.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a contract for specifying values associated with a unique key.
|
||||
/// </summary>
|
||||
public interface IParameters : IEnumerable<KeyValuePair<string, object>>
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the specified key and value to the parameter collection.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the parameter to add.</param>
|
||||
/// <param name="value">The value of the parameter to add.</param>
|
||||
void Add(string key, object value);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the <see cref="IParameters"/> contains the specified <paramref name="key"/>.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to search the parameters for existence.</param>
|
||||
/// <returns>true if the <see cref="IParameters"/> contains a parameter with the specified key; otherwise, false.</returns>
|
||||
bool ContainsKey(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of parameters contained in the <see cref="IParameters"/>.
|
||||
/// </summary>
|
||||
int Count { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection containing the keys in the <see cref="IParameters"/>.
|
||||
/// </summary>
|
||||
IEnumerable<string> Keys { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter associated with the specified <paramref name="key"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the parameter to get.</typeparam>
|
||||
/// <param name="key">The key of the parameter to find.</param>
|
||||
/// <returns>A matching value of <typeparamref name="T"/> if it exists.</returns>
|
||||
T GetValue<T>(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter associated with the specified <paramref name="key"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the parameter to get.</typeparam>
|
||||
/// <param name="key">The key of the parameter to find.</param>
|
||||
/// <returns>An <see cref="IEnumerable{T}"/> of all the values referenced by key.</returns>
|
||||
IEnumerable<T> GetValues<T>(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter associated with the specified <paramref name="key"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the parameter to get.</typeparam>
|
||||
/// <param name="key">The key of the parameter to get.</param>
|
||||
/// <param name="value">
|
||||
/// When this method returns, contains the parameter associated with the specified key,
|
||||
/// if the key is found; otherwise, the default value for the type of the value parameter.
|
||||
/// </param>
|
||||
/// <returns>true if the <see cref="IParameters"/> contains a parameter with the specified key; otherwise, false.</returns>
|
||||
bool TryGetValue<T>(string key, out T value);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter associated with the specified key (legacy).
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the parameter to get.</param>
|
||||
/// <returns>A matching value if it exists.</returns>
|
||||
object this[string key] { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Prism.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a generic parameters base class used for Dialog Parameters and Navigation Parameters.
|
||||
/// </summary>
|
||||
public abstract class ParametersBase : IParameters, IEnumerable<KeyValuePair<string, object>>
|
||||
{
|
||||
private readonly List<KeyValuePair<string, object>> _entries = new List<KeyValuePair<string, object>>();
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor.
|
||||
/// </summary>
|
||||
protected ParametersBase()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a list of parameters.
|
||||
/// </summary>
|
||||
/// <param name="query">Query string to be parsed.</param>
|
||||
protected ParametersBase(string query)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(query))
|
||||
{
|
||||
int num = query.Length;
|
||||
for (int i = ((query.Length > 0) && (query[0] == '?')) ? 1 : 0; i < num; i++)
|
||||
{
|
||||
int startIndex = i;
|
||||
int num4 = -1;
|
||||
while (i < num)
|
||||
{
|
||||
char ch = query[i];
|
||||
if (ch == '=')
|
||||
{
|
||||
if (num4 < 0)
|
||||
{
|
||||
num4 = i;
|
||||
}
|
||||
}
|
||||
else if (ch == '&')
|
||||
{
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
string key = null;
|
||||
string value;
|
||||
if (num4 >= 0)
|
||||
{
|
||||
key = query.Substring(startIndex, num4 - startIndex);
|
||||
value = query.Substring(num4 + 1, (i - num4) - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = query.Substring(startIndex, i - startIndex);
|
||||
}
|
||||
|
||||
if (key != null)
|
||||
Add(Uri.UnescapeDataString(key), Uri.UnescapeDataString(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches Parameter collection and returns value if Collection contains key.
|
||||
/// Otherwise returns null.
|
||||
/// </summary>
|
||||
/// <param name="key">The key for the value to be returned.</param>
|
||||
/// <returns>The value of the parameter referenced by the key; otherwise <c>null</c>.</returns>
|
||||
public object this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (var entry in _entries)
|
||||
{
|
||||
if (string.Compare(entry.Key, key, StringComparison.Ordinal) == 0)
|
||||
{
|
||||
return entry.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The count, or number, of parameters in collection.
|
||||
/// </summary>
|
||||
public int Count => _entries.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Returns an IEnumerable of the Keys in the collection.
|
||||
/// </summary>
|
||||
public IEnumerable<string> Keys =>
|
||||
_entries.Select(x => x.Key);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the key and value to the parameters collection.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to reference this value in the parameters collection.</param>
|
||||
/// <param name="value">The value of the parameter to store.</param>
|
||||
public void Add(string key, object value) =>
|
||||
_entries.Add(new KeyValuePair<string, object>(key, value));
|
||||
|
||||
/// <summary>
|
||||
/// Checks collection for presence of key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key to check in the collection.</param>
|
||||
/// <returns><c>true</c> if key exists; else returns <c>false</c>.</returns>
|
||||
public bool ContainsKey(string key) =>
|
||||
_entries.ContainsKey(key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an enumerator for the KeyValuePairs in parameter collection.
|
||||
/// </summary>
|
||||
/// <returns>Enumerator.</returns>
|
||||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() =>
|
||||
_entries.GetEnumerator();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the value of the member referenced by key.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of object to be returned.</typeparam>
|
||||
/// <param name="key">The key for the value to be returned.</param>
|
||||
/// <returns>Returns a matching parameter of <typeparamref name="T"/> if one exists in the Collection.</returns>
|
||||
public T GetValue<T>(string key) =>
|
||||
_entries.GetValue<T>(key);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an IEnumerable of all parameters.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type for the values to be returned.</typeparam>
|
||||
/// <param name="key">The key for the values to be returned.</param>
|
||||
///<returns>Returns a IEnumerable of all the instances of type <typeparamref name="T"/>.</returns>
|
||||
public IEnumerable<T> GetValues<T>(string key) =>
|
||||
_entries.GetValues<T>(key);
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the parameter collection contains the value.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type for the values to be returned.</typeparam>
|
||||
/// <param name="key">The key for the value to be returned.</param>
|
||||
/// <param name="value">Value of the returned parameter if it exists.</param>
|
||||
public bool TryGetValue<T>(string key, out T value) =>
|
||||
_entries.TryGetValue(key, out value);
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() =>
|
||||
GetEnumerator();
|
||||
|
||||
/// <summary>
|
||||
/// Converts parameter collection to a parameter string.
|
||||
/// </summary>
|
||||
/// <returns>A string representation of the parameters.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
var queryBuilder = new StringBuilder();
|
||||
|
||||
if (_entries.Count > 0)
|
||||
{
|
||||
queryBuilder.Append('?');
|
||||
var first = true;
|
||||
|
||||
foreach (var kvp in _entries)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
queryBuilder.Append('&');
|
||||
}
|
||||
else
|
||||
{
|
||||
first = false;
|
||||
}
|
||||
|
||||
queryBuilder.Append(Uri.EscapeDataString(kvp.Key));
|
||||
queryBuilder.Append('=');
|
||||
queryBuilder.Append(Uri.EscapeDataString(kvp.Value != null ? kvp.Value.ToString() : ""));
|
||||
}
|
||||
}
|
||||
|
||||
return queryBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a collection of parameters to the local parameter list.
|
||||
/// </summary>
|
||||
/// <param name="parameters">An IEnumerable of KeyValuePairs to add to the current parameter list.</param>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void FromParameters(IEnumerable<KeyValuePair<string, object>> parameters) =>
|
||||
_entries.AddRange(parameters);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace Prism.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for Navigation or Dialog parameters
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static class ParametersExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Searches <paramref name="parameters"/> for <paramref name="key"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the parameter to return</typeparam>
|
||||
/// <param name="parameters">A collection of parameters to search</param>
|
||||
/// <param name="key">The key of the parameter to find</param>
|
||||
/// <returns>A matching value of <typeparamref name="T"/> if it exists</returns>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static T GetValue<T>(this IEnumerable<KeyValuePair<string, object>> parameters, string key) =>
|
||||
(T)GetValue(parameters, key, typeof(T));
|
||||
|
||||
/// <summary>
|
||||
/// Searches <paramref name="parameters"/> for value referenced by <paramref name="key"/>
|
||||
/// </summary>
|
||||
/// <param name="parameters">A collection of parameters to search</param>
|
||||
/// <param name="key">The key of the parameter to find</param>
|
||||
/// <param name="type">The type of the parameter to return</param>
|
||||
/// <returns>A matching value of <paramref name="type"/> if it exists</returns>
|
||||
/// <exception cref="InvalidCastException">Unable to convert the value of Type</exception>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static object GetValue(this IEnumerable<KeyValuePair<string, object>> parameters, string key, Type type)
|
||||
{
|
||||
foreach (var kvp in parameters)
|
||||
{
|
||||
if (string.Compare(kvp.Key, key, StringComparison.Ordinal) == 0)
|
||||
{
|
||||
if (TryGetValueInternal(kvp, type, out var value))
|
||||
return value;
|
||||
|
||||
throw new InvalidCastException($"Unable to convert the value of Type '{kvp.Value.GetType().FullName}' to '{type.FullName}' for the key '{key}' ");
|
||||
}
|
||||
}
|
||||
|
||||
return GetDefault(type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches <paramref name="parameters"/> for value referenced by <paramref name="key"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the parameter to return</typeparam>
|
||||
/// <param name="parameters">A collection of parameters to search</param>
|
||||
/// <param name="key">The key of the parameter to find</param>
|
||||
/// <param name="value">The value of parameter to return</param>
|
||||
/// <returns>Success if value is found; otherwise returns <c>false</c></returns>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static bool TryGetValue<T>(this IEnumerable<KeyValuePair<string, object>> parameters, string key, out T value)
|
||||
{
|
||||
var type = typeof(T);
|
||||
|
||||
foreach (var kvp in parameters)
|
||||
{
|
||||
if (string.Compare(kvp.Key, key, StringComparison.Ordinal) == 0)
|
||||
{
|
||||
var success = TryGetValueInternal(kvp, typeof(T), out object valueAsObject);
|
||||
value = (T)valueAsObject;
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches <paramref name="parameters"/> for value referenced by <paramref name="key"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the parameter to return</typeparam>
|
||||
/// <param name="parameters">A collection of parameters to search</param>
|
||||
/// <param name="key">The key of the parameter to find</param>
|
||||
/// <returns>An IEnumerable{T} of all the values referenced by key</returns>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static IEnumerable<T> GetValues<T>(this IEnumerable<KeyValuePair<string, object>> parameters, string key)
|
||||
{
|
||||
List<T> values = new List<T>();
|
||||
var type = typeof(T);
|
||||
|
||||
foreach (var kvp in parameters)
|
||||
{
|
||||
if (string.Compare(kvp.Key, key, StringComparison.Ordinal) == 0)
|
||||
{
|
||||
TryGetValueInternal(kvp, type, out var value);
|
||||
values.Add((T)value);
|
||||
}
|
||||
}
|
||||
|
||||
return values.AsEnumerable();
|
||||
}
|
||||
|
||||
private static bool TryGetValueInternal(KeyValuePair<string, object> kvp, Type type, out object value)
|
||||
{
|
||||
value = GetDefault(type);
|
||||
var success = false;
|
||||
if (kvp.Value == null)
|
||||
{
|
||||
success = true;
|
||||
}
|
||||
else if (kvp.Value.GetType() == type)
|
||||
{
|
||||
success = true;
|
||||
value = kvp.Value;
|
||||
}
|
||||
else if (type.IsAssignableFrom(kvp.Value.GetType()))
|
||||
{
|
||||
success = true;
|
||||
value = kvp.Value;
|
||||
}
|
||||
else if (type.IsEnum)
|
||||
{
|
||||
var valueAsString = kvp.Value.ToString();
|
||||
if (Enum.IsDefined(type, valueAsString))
|
||||
{
|
||||
success = true;
|
||||
value = Enum.Parse(type, valueAsString);
|
||||
}
|
||||
else if (int.TryParse(valueAsString, out var numericValue))
|
||||
{
|
||||
success = true;
|
||||
value = Enum.ToObject(type, numericValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (!success && type.GetInterface("System.IConvertible") != null)
|
||||
{
|
||||
success = true;
|
||||
value = Convert.ChangeType(kvp.Value, type);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if key exists in parameter collection
|
||||
/// </summary>
|
||||
/// <param name="parameters">IEnumerable to search</param>
|
||||
/// <param name="key">The key to search the <paramref name="parameters"/> for existence</param>
|
||||
/// <returns><c>true</c> if key exists; <c>false</c> otherwise</returns>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static bool ContainsKey(this IEnumerable<KeyValuePair<string, object>> parameters, string key) =>
|
||||
parameters.Any(x => string.Compare(x.Key, key, StringComparison.Ordinal) == 0);
|
||||
|
||||
private static object GetDefault(Type type)
|
||||
{
|
||||
if (type.IsValueType)
|
||||
{
|
||||
return Activator.CreateInstance(type);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
using _29WxOrderWpf.Commands;
|
||||
using _29WxOrderWpf.Common;
|
||||
using _29WxOrderWpf.Ctrls.PDDInvoice.ViewModels;
|
||||
using Prism.Services.Dialogs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -22,18 +24,25 @@ namespace _29WxOrderWpf.Ctrls.PDDInvoice;
|
||||
/// <summary>
|
||||
/// PDDInvoiceDialog.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class PDDInvoiceDialog : UserControl
|
||||
public partial class PDDInvoiceDialog : UserControl, IDialogAware
|
||||
{
|
||||
public PDDInvoiceDialog()
|
||||
public PDDInvoiceDialog(InvoiceConfig config)
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = this;
|
||||
Config = NaiBa.Util.Helper.ConfigHelper.LoadConfig<InvoiceConfig>(ConfigPath);
|
||||
Config = new InvoiceConfig();
|
||||
Config.Assign(config);
|
||||
}
|
||||
public string Title { get; set; }
|
||||
public event Action<IDialogResult> RequestClose;
|
||||
|
||||
private void PDDInvoiceDialog_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
public void OnDialogOpened(IDialogParameters parameters)
|
||||
{
|
||||
Title = "设置";
|
||||
}
|
||||
|
||||
private void ViewModel_RequestClose()
|
||||
@@ -44,21 +53,35 @@ public partial class PDDInvoiceDialog : UserControl
|
||||
}
|
||||
|
||||
|
||||
private const string ConfigPath = "./invoice.config";
|
||||
public InvoiceConfig Config { get; }
|
||||
|
||||
|
||||
public ICommand ConfirmCommand => new DelegateCommand(Confirm);
|
||||
|
||||
private void Confirm()
|
||||
{
|
||||
NaiBa.Util.Helper.ConfigHelper.SaveConfig(ConfigPath, Config);
|
||||
ViewModel_RequestClose();
|
||||
RequestClose?.Invoke(new DialogResult(ButtonResult.OK, new DialogParameters
|
||||
{
|
||||
{ "config",Config}
|
||||
}));
|
||||
}
|
||||
public ICommand CancelCommand => new DelegateCommand(Cancel);
|
||||
|
||||
|
||||
private void Cancel()
|
||||
{
|
||||
ViewModel_RequestClose();
|
||||
RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel));
|
||||
}
|
||||
|
||||
public bool CanCloseDialog()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnDialogClosed()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ using MAX.Core.Helpers;
|
||||
using NaiBa.Util.Extension;
|
||||
using Newtonsoft.Json;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using Prism.Services.Dialogs;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
@@ -475,13 +476,17 @@ public partial class PDDInvoiceViewModel : BindableBaseEx
|
||||
|
||||
private void ShowSettingDialog()
|
||||
{
|
||||
var view = new PDDInvoiceDialog();
|
||||
new DialogWindow
|
||||
var view = new PDDInvoiceDialog(Config);
|
||||
DialogService.ShowDialog(view, null, result =>
|
||||
{
|
||||
Title = "设置",
|
||||
Content = view,
|
||||
}.ShowDialog();
|
||||
Config = view.Config;
|
||||
if (result.Result == ButtonResult.OK)
|
||||
{
|
||||
Config.Assign(view.Config);
|
||||
NaiBa.Util.Helper.ConfigHelper.SaveConfig(ConfigPath, Config);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public event EventHandler<int> BatchInvoiceChanged;
|
||||
@@ -506,7 +511,7 @@ public partial class PDDInvoiceViewModel : BindableBaseEx
|
||||
BottomMsg = "已取消批量开票";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (AmountTotal >= Config.MaxAmount)
|
||||
{
|
||||
return;
|
||||
@@ -537,6 +542,11 @@ public partial class PDDInvoiceViewModel : BindableBaseEx
|
||||
order.IsSelected = false;
|
||||
success++;
|
||||
AmountTotal += order.order_amount / 100m;
|
||||
if (Config.IsSaveData)
|
||||
{
|
||||
var temp = OrderInvoiceInfoList?.FirstOrDefault(a => a.order_sn == order.order_sn);
|
||||
if (temp != null) temp.IsInvoiced = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -547,6 +557,12 @@ public partial class PDDInvoiceViewModel : BindableBaseEx
|
||||
BottomRMsg = $"批量开票状态:成功 {success} 个,失败 {fail} 个。总金额:{AmountTotal.ToString("N2")}";
|
||||
StatisticsInvoiceAmount();
|
||||
await Task.Delay(1000);
|
||||
|
||||
if (Config.IsSaveData)
|
||||
{
|
||||
SaveOrderInvoiceInfo();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -716,9 +732,10 @@ public partial class PDDInvoiceViewModel : BindableBaseEx
|
||||
}
|
||||
}
|
||||
StatisticsInvoiceAmount();
|
||||
|
||||
|
||||
SaveOrderInvoiceInfo();
|
||||
if (Config.IsSaveData)
|
||||
{
|
||||
SaveOrderInvoiceInfo();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -897,4 +914,12 @@ public class InvoiceConfig
|
||||
public string TaxNo { get; set; }
|
||||
public decimal MaxAmount { get; set; }
|
||||
public bool IsSaveData { get; set; }
|
||||
|
||||
public void Assign(InvoiceConfig config)
|
||||
{
|
||||
Title = config.Title;
|
||||
TaxNo = config.TaxNo;
|
||||
MaxAmount = config.MaxAmount;
|
||||
IsSaveData = config.IsSaveData;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user