diff --git a/29WxOrderWpf/Common/DialogWindow.xaml.cs b/29WxOrderWpf/Common/DialogWindow.xaml.cs
index b650996..52c9b84 100644
--- a/29WxOrderWpf/Common/DialogWindow.xaml.cs
+++ b/29WxOrderWpf/Common/DialogWindow.xaml.cs
@@ -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
///
/// DialogWindow.xaml 的交互逻辑
///
- 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);
diff --git a/29WxOrderWpf/Common/Dialogs/ButtonResult.cs b/29WxOrderWpf/Common/Dialogs/ButtonResult.cs
new file mode 100644
index 0000000..eeaa6ea
--- /dev/null
+++ b/29WxOrderWpf/Common/Dialogs/ButtonResult.cs
@@ -0,0 +1,41 @@
+namespace Prism.Services.Dialogs
+{
+ ///
+ /// The result of the dialog.
+ ///
+ public enum ButtonResult
+ {
+ ///
+ /// Abort.
+ ///
+ Abort = 3,
+ ///
+ /// Cancel.
+ ///
+ Cancel = 2,
+ ///
+ /// Ignore.
+ ///
+ Ignore = 5,
+ ///
+ /// No.
+ ///
+ No = 7,
+ ///
+ /// No result returned.
+ ///
+ None = 0,
+ ///
+ /// OK.
+ ///
+ OK = 1,
+ ///
+ /// Retry.
+ ///
+ Retry = 4,
+ ///
+ /// Yes.
+ ///
+ Yes = 6
+ }
+}
diff --git a/29WxOrderWpf/Common/Dialogs/Dialog.cs b/29WxOrderWpf/Common/Dialogs/Dialog.cs
new file mode 100644
index 0000000..caf978e
--- /dev/null
+++ b/29WxOrderWpf/Common/Dialogs/Dialog.cs
@@ -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
+{
+ ///
+ /// This class contains attached properties.
+ ///
+ public class Dialog
+ {
+ ///
+ /// Identifies the WindowStyle attached property.
+ ///
+ ///
+ /// This attached property is used to specify the style of a .
+ ///
+ public static readonly DependencyProperty WindowStyleProperty =
+ DependencyProperty.RegisterAttached("WindowStyle", typeof(Style), typeof(Dialog), new PropertyMetadata(null));
+
+ ///
+ /// Gets the value for the attached property.
+ ///
+ /// The target element.
+ /// The attached to the element.
+ public static Style GetWindowStyle(DependencyObject obj)
+ {
+ return (Style)obj.GetValue(WindowStyleProperty);
+ }
+
+ ///
+ /// Sets the attached property.
+ ///
+ /// The target element.
+ /// The Style to attach.
+ public static void SetWindowStyle(DependencyObject obj, Style value)
+ {
+ obj.SetValue(WindowStyleProperty, value);
+ }
+
+#if !HAS_UWP && !HAS_WINUI
+ ///
+ /// Identifies the WindowStartupLocation attached property.
+ ///
+ ///
+ /// This attached property is used to specify the startup location of a .
+ ///
+ public static readonly DependencyProperty WindowStartupLocationProperty =
+ DependencyProperty.RegisterAttached("WindowStartupLocation", typeof(WindowStartupLocation), typeof(Dialog), new UIPropertyMetadata(OnWindowStartupLocationChanged));
+
+ ///
+ /// Gets the value for the attached property.
+ ///
+ /// The target element.
+ /// The attached to the element.
+ public static WindowStartupLocation GetWindowStartupLocation(DependencyObject obj)
+ {
+ return (WindowStartupLocation)obj.GetValue(WindowStartupLocationProperty);
+ }
+
+ ///
+ /// Sets the attached property.
+ ///
+ /// The target element.
+ /// The WindowStartupLocation to attach.
+ 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
+ }
+}
diff --git a/29WxOrderWpf/Common/Dialogs/DialogParameters.cs b/29WxOrderWpf/Common/Dialogs/DialogParameters.cs
new file mode 100644
index 0000000..b853673
--- /dev/null
+++ b/29WxOrderWpf/Common/Dialogs/DialogParameters.cs
@@ -0,0 +1,24 @@
+using Prism.Common;
+
+namespace Prism.Services.Dialogs
+{
+ ///
+ /// Represents Dialog parameters.
+ ///
+ ///
+ /// This class can be used to to pass object parameters during the showing and closing of Dialogs.
+ ///
+ public class DialogParameters : ParametersBase, IDialogParameters
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DialogParameters() : base() { }
+
+ ///
+ /// Constructs a list of parameters.
+ ///
+ /// Query string to be parsed.
+ public DialogParameters(string query) : base(query) { }
+ }
+}
diff --git a/29WxOrderWpf/Common/Dialogs/DialogResult.cs b/29WxOrderWpf/Common/Dialogs/DialogResult.cs
new file mode 100644
index 0000000..f0c9a8c
--- /dev/null
+++ b/29WxOrderWpf/Common/Dialogs/DialogResult.cs
@@ -0,0 +1,44 @@
+namespace Prism.Services.Dialogs
+{
+ ///
+ /// An that contains from the dialog
+ /// and the of the dialog.
+ ///
+ public class DialogResult : IDialogResult
+ {
+ ///
+ /// The parameters from the dialog.
+ ///
+ public IDialogParameters Parameters { get; private set; } = new DialogParameters();
+
+ ///
+ /// The result of the dialog.
+ ///
+ public ButtonResult Result { get; private set; } = ButtonResult.None;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public DialogResult() { }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The result of the dialog.
+ public DialogResult(ButtonResult result)
+ {
+ Result = result;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The result of the dialog.
+ /// The parameters from the dialog.
+ public DialogResult(ButtonResult result, IDialogParameters parameters)
+ {
+ Result = result;
+ Parameters = parameters;
+ }
+ }
+}
diff --git a/29WxOrderWpf/Common/Dialogs/DialogService.cs b/29WxOrderWpf/Common/Dialogs/DialogService.cs
new file mode 100644
index 0000000..aa80c0e
--- /dev/null
+++ b/29WxOrderWpf/Common/Dialogs/DialogService.cs
@@ -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
+{
+ ///
+ /// 静态弹窗服务:不依赖容器,直接传入 View 实例弹出。
+ /// ViewModel 需实现 IDialogAware。
+ ///
+ public static class DialogService
+ {
+ // ========== 对外接口 ==========
+
+ /// 非模态弹出
+ public static void Show(FrameworkElement view,
+ IDialogParameters parameters = null,
+ Action callback = null,
+ IDialogWindow window = null)
+ {
+ ShowInternal(view, parameters, callback, false, window);
+ }
+
+ /// 模态弹出
+ public static void ShowDialog(FrameworkElement view,
+ IDialogParameters parameters = null,
+ Action callback = null,
+ IDialogWindow window = null)
+ {
+ ShowInternal(view, parameters, callback, true, window);
+ }
+
+ // ========== 内部实现 ==========
+
+ private static void ShowInternal(FrameworkElement view,
+ IDialogParameters parameters,
+ Action 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();
+ }
+
+ ///
+ /// 把 View 挂到 DialogWindow 上,并触发 OnDialogOpened。
+ ///
+ 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);
+ }
+
+ ///
+ /// 绑定 DialogWindow 的生命周期事件。
+ ///
+ private static void ConfigureDialogWindowEvents(IDialogWindow dialogWindow, Action callback)
+ {
+ Action 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;
+ }
+
+ ///
+ /// 设置 DialogWindow 的 Style / Content / DataContext / Owner。
+ ///
+ 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()
+ .FirstOrDefault(x => x.IsActive);
+ }
+
+ ///
+ /// 从 window.Content 或 window.DataContext 里拿 IDialogAware。
+ /// 替代 Prism 的 dialogWindow.GetDialogViewModel() 扩展方法。
+ ///
+ 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");
+ }
+ }
+}
diff --git a/29WxOrderWpf/Common/Dialogs/IDialogAware.cs b/29WxOrderWpf/Common/Dialogs/IDialogAware.cs
new file mode 100644
index 0000000..7117f57
--- /dev/null
+++ b/29WxOrderWpf/Common/Dialogs/IDialogAware.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace Prism.Services.Dialogs
+{
+ ///
+ /// Interface that provides dialog functions and events to ViewModels.
+ ///
+ public interface IDialogAware
+ {
+ ///
+ /// Determines if the dialog can be closed.
+ ///
+ /// If true the dialog can be closed. If false the dialog will not close.
+ bool CanCloseDialog();
+
+ ///
+ /// Called when the dialog is closed.
+ ///
+ void OnDialogClosed();
+
+ ///
+ /// Called when the dialog is opened.
+ ///
+ /// The parameters passed to the dialog.
+ void OnDialogOpened(IDialogParameters parameters);
+
+ ///
+ /// The title of the dialog that will show in the window title bar.
+ ///
+ string Title { get; }
+
+ ///
+ /// Instructs the to close the dialog.
+ ///
+ event Action RequestClose;
+ }
+}
diff --git a/29WxOrderWpf/Common/Dialogs/IDialogParameters.cs b/29WxOrderWpf/Common/Dialogs/IDialogParameters.cs
new file mode 100644
index 0000000..0083505
--- /dev/null
+++ b/29WxOrderWpf/Common/Dialogs/IDialogParameters.cs
@@ -0,0 +1,63 @@
+using System.Collections.Generic;
+
+namespace Prism.Services.Dialogs
+{
+ ///
+ /// Represents Dialog parameters.
+ ///
+ ///
+ /// A class that implements this interface can be used to pass
+ /// object parameters during the showing and closing of Dialogs.
+ ///
+ public interface IDialogParameters
+ {
+ ///
+ /// Adds the key and value to the collection.
+ ///
+ /// The key to reference this parameter value in the collection.
+ /// The parameter value to store.
+ void Add(string key, object value);
+
+ ///
+ /// Checks the collection for the presence of a key.
+ ///
+ /// The key to check.
+ /// true if key exists; false otherwise.
+ bool ContainsKey(string key);
+
+ ///
+ /// The number of parameters in the collection.
+ ///
+ int Count { get; }
+
+ ///
+ /// The keys in the collection.
+ ///
+ IEnumerable Keys { get; }
+
+ ///
+ /// Gets the parameter value referenced by a key.
+ ///
+ /// The type of object to be returned.
+ /// The key of the parameter value to be returned.
+ /// The matching parameter of type .
+ T GetValue(string key);
+
+ ///
+ /// Gets all parameter values referenced by a key.
+ ///
+ /// The type of object to be returned.
+ /// The key of the parameter values to be returned.
+ ///All matching parameter values of type .
+ IEnumerable GetValues(string key);
+
+ ///
+ /// Gets the parameter value if the referenced key exists.
+ ///
+ /// The type of object to be returned.
+ /// The key of the parameter value to be returned.
+ /// The matching parameter of type if the key exists.
+ /// true if the parameter exists; false otherwise.
+ bool TryGetValue(string key, out T value);
+ }
+}
diff --git a/29WxOrderWpf/Common/Dialogs/IDialogResult.cs b/29WxOrderWpf/Common/Dialogs/IDialogResult.cs
new file mode 100644
index 0000000..1fefeb9
--- /dev/null
+++ b/29WxOrderWpf/Common/Dialogs/IDialogResult.cs
@@ -0,0 +1,19 @@
+namespace Prism.Services.Dialogs
+{
+ ///
+ /// Contains from the dialog
+ /// and the of the dialog.
+ ///
+ public interface IDialogResult
+ {
+ ///
+ /// The parameters from the dialog.
+ ///
+ IDialogParameters Parameters { get; }
+
+ ///
+ /// The result of the dialog.
+ ///
+ ButtonResult Result { get; }
+ }
+}
diff --git a/29WxOrderWpf/Common/Dialogs/IDialogWindow.cs b/29WxOrderWpf/Common/Dialogs/IDialogWindow.cs
new file mode 100644
index 0000000..69905d6
--- /dev/null
+++ b/29WxOrderWpf/Common/Dialogs/IDialogWindow.cs
@@ -0,0 +1,71 @@
+using System;
+using System.ComponentModel;
+using System.Windows;
+
+namespace Prism.Services.Dialogs
+{
+ ///
+ /// Interface for a dialog hosting window.
+ ///
+ public interface IDialogWindow
+ {
+ ///
+ /// Dialog content.
+ ///
+ object Content { get; set; }
+
+ ///
+ /// Close the window.
+ ///
+ void Close();
+
+ ///
+ /// The window's owner.
+ ///
+ Window Owner { get; set; }
+
+ ///
+ /// Show a non-modal dialog.
+ ///
+ void Show();
+
+ ///
+ /// Show a modal dialog.
+ ///
+ ///
+ bool? ShowDialog();
+
+ ///
+ /// The data context of the window.
+ ///
+ ///
+ /// The data context must implement .
+ ///
+ object DataContext { get; set; }
+
+ ///
+ /// Called when the window is loaded.
+ ///
+ event RoutedEventHandler Loaded;
+
+ ///
+ /// Called when the window is closed.
+ ///
+ event EventHandler Closed;
+
+ ///
+ /// Called when the window is closing.
+ ///
+ event CancelEventHandler Closing;
+
+ ///
+ /// The result of the dialog.
+ ///
+ IDialogResult Result { get; set; }
+
+ ///
+ /// The window style.
+ ///
+ Style Style { get; set; }
+ }
+}
diff --git a/29WxOrderWpf/Common/Dialogs/IParameters.cs b/29WxOrderWpf/Common/Dialogs/IParameters.cs
new file mode 100644
index 0000000..2202587
--- /dev/null
+++ b/29WxOrderWpf/Common/Dialogs/IParameters.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Prism.Common
+{
+ ///
+ /// Defines a contract for specifying values associated with a unique key.
+ ///
+ public interface IParameters : IEnumerable>
+ {
+ ///
+ /// Adds the specified key and value to the parameter collection.
+ ///
+ /// The key of the parameter to add.
+ /// The value of the parameter to add.
+ void Add(string key, object value);
+
+ ///
+ /// Determines whether the contains the specified .
+ ///
+ /// The key to search the parameters for existence.
+ /// true if the contains a parameter with the specified key; otherwise, false.
+ bool ContainsKey(string key);
+
+ ///
+ /// Gets the number of parameters contained in the .
+ ///
+ int Count { get; }
+
+ ///
+ /// Gets a collection containing the keys in the .
+ ///
+ IEnumerable Keys { get; }
+
+ ///
+ /// Gets the parameter associated with the specified .
+ ///
+ /// The type of the parameter to get.
+ /// The key of the parameter to find.
+ /// A matching value of if it exists.
+ T GetValue(string key);
+
+ ///
+ /// Gets the parameter associated with the specified .
+ ///
+ /// The type of the parameter to get.
+ /// The key of the parameter to find.
+ /// An of all the values referenced by key.
+ IEnumerable GetValues(string key);
+
+ ///
+ /// Gets the parameter associated with the specified .
+ ///
+ /// The type of the parameter to get.
+ /// The key of the parameter to get.
+ ///
+ /// 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.
+ ///
+ /// true if the contains a parameter with the specified key; otherwise, false.
+ bool TryGetValue(string key, out T value);
+
+ ///
+ /// Gets the parameter associated with the specified key (legacy).
+ ///
+ /// The key of the parameter to get.
+ /// A matching value if it exists.
+ object this[string key] { get; }
+ }
+}
diff --git a/29WxOrderWpf/Common/Dialogs/ParametersBase.cs b/29WxOrderWpf/Common/Dialogs/ParametersBase.cs
new file mode 100644
index 0000000..2bbd7b2
--- /dev/null
+++ b/29WxOrderWpf/Common/Dialogs/ParametersBase.cs
@@ -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
+{
+ ///
+ /// This is a generic parameters base class used for Dialog Parameters and Navigation Parameters.
+ ///
+ public abstract class ParametersBase : IParameters, IEnumerable>
+ {
+ private readonly List> _entries = new List>();
+
+ ///
+ /// Default constructor.
+ ///
+ protected ParametersBase()
+ {
+ }
+
+ ///
+ /// Constructs a list of parameters.
+ ///
+ /// Query string to be parsed.
+ 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));
+ }
+ }
+ }
+
+ ///
+ /// Searches Parameter collection and returns value if Collection contains key.
+ /// Otherwise returns null.
+ ///
+ /// The key for the value to be returned.
+ /// The value of the parameter referenced by the key; otherwise null.
+ 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;
+ }
+ }
+
+ ///
+ /// The count, or number, of parameters in collection.
+ ///
+ public int Count => _entries.Count;
+
+ ///
+ /// Returns an IEnumerable of the Keys in the collection.
+ ///
+ public IEnumerable Keys =>
+ _entries.Select(x => x.Key);
+
+ ///
+ /// Adds the key and value to the parameters collection.
+ ///
+ /// The key to reference this value in the parameters collection.
+ /// The value of the parameter to store.
+ public void Add(string key, object value) =>
+ _entries.Add(new KeyValuePair(key, value));
+
+ ///
+ /// Checks collection for presence of key.
+ ///
+ /// The key to check in the collection.
+ /// true if key exists; else returns false.
+ public bool ContainsKey(string key) =>
+ _entries.ContainsKey(key);
+
+ ///
+ /// Gets an enumerator for the KeyValuePairs in parameter collection.
+ ///
+ /// Enumerator.
+ public IEnumerator> GetEnumerator() =>
+ _entries.GetEnumerator();
+
+ ///
+ /// Returns the value of the member referenced by key.
+ ///
+ /// The type of object to be returned.
+ /// The key for the value to be returned.
+ /// Returns a matching parameter of if one exists in the Collection.
+ public T GetValue(string key) =>
+ _entries.GetValue(key);
+
+ ///
+ /// Returns an IEnumerable of all parameters.
+ ///
+ /// The type for the values to be returned.
+ /// The key for the values to be returned.
+ ///Returns a IEnumerable of all the instances of type .
+ public IEnumerable GetValues(string key) =>
+ _entries.GetValues(key);
+
+ ///
+ /// Checks to see if the parameter collection contains the value.
+ ///
+ /// The type for the values to be returned.
+ /// The key for the value to be returned.
+ /// Value of the returned parameter if it exists.
+ public bool TryGetValue(string key, out T value) =>
+ _entries.TryGetValue(key, out value);
+
+ IEnumerator IEnumerable.GetEnumerator() =>
+ GetEnumerator();
+
+ ///
+ /// Converts parameter collection to a parameter string.
+ ///
+ /// A string representation of the parameters.
+ 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();
+ }
+
+ ///
+ /// Adds a collection of parameters to the local parameter list.
+ ///
+ /// An IEnumerable of KeyValuePairs to add to the current parameter list.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void FromParameters(IEnumerable> parameters) =>
+ _entries.AddRange(parameters);
+ }
+}
diff --git a/29WxOrderWpf/Common/Dialogs/ParametersExtensions.cs b/29WxOrderWpf/Common/Dialogs/ParametersExtensions.cs
new file mode 100644
index 0000000..644da68
--- /dev/null
+++ b/29WxOrderWpf/Common/Dialogs/ParametersExtensions.cs
@@ -0,0 +1,163 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+
+namespace Prism.Common
+{
+ ///
+ /// Extension methods for Navigation or Dialog parameters
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static class ParametersExtensions
+ {
+ ///
+ /// Searches for
+ ///
+ /// The type of the parameter to return
+ /// A collection of parameters to search
+ /// The key of the parameter to find
+ /// A matching value of if it exists
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static T GetValue(this IEnumerable> parameters, string key) =>
+ (T)GetValue(parameters, key, typeof(T));
+
+ ///
+ /// Searches for value referenced by
+ ///
+ /// A collection of parameters to search
+ /// The key of the parameter to find
+ /// The type of the parameter to return
+ /// A matching value of if it exists
+ /// Unable to convert the value of Type
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static object GetValue(this IEnumerable> 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);
+ }
+
+ ///
+ /// Searches for value referenced by
+ ///
+ /// The type of the parameter to return
+ /// A collection of parameters to search
+ /// The key of the parameter to find
+ /// The value of parameter to return
+ /// Success if value is found; otherwise returns false
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static bool TryGetValue(this IEnumerable> 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;
+ }
+
+ ///
+ /// Searches for value referenced by
+ ///
+ /// The type of the parameter to return
+ /// A collection of parameters to search
+ /// The key of the parameter to find
+ /// An IEnumerable{T} of all the values referenced by key
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static IEnumerable GetValues(this IEnumerable> parameters, string key)
+ {
+ List values = new List();
+ 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 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;
+ }
+
+ ///
+ /// Checks to see if key exists in parameter collection
+ ///
+ /// IEnumerable to search
+ /// The key to search the for existence
+ /// true if key exists; false otherwise
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static bool ContainsKey(this IEnumerable> 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;
+ }
+ }
+}
diff --git a/29WxOrderWpf/Ctrls/PDDInvoice/PDDInvoiceDialog.xaml.cs b/29WxOrderWpf/Ctrls/PDDInvoice/PDDInvoiceDialog.xaml.cs
index 3d4c862..4aa6a26 100644
--- a/29WxOrderWpf/Ctrls/PDDInvoice/PDDInvoiceDialog.xaml.cs
+++ b/29WxOrderWpf/Ctrls/PDDInvoice/PDDInvoiceDialog.xaml.cs
@@ -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;
///
/// PDDInvoiceDialog.xaml 的交互逻辑
///
-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(ConfigPath);
+ Config = new InvoiceConfig();
+ Config.Assign(config);
}
+ public string Title { get; set; }
+ public event Action 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()
+ {
+
+ }
+
+
}
diff --git a/29WxOrderWpf/Ctrls/PDDInvoice/ViewModels/PDDInvoiceViewModel.cs b/29WxOrderWpf/Ctrls/PDDInvoice/ViewModels/PDDInvoiceViewModel.cs
index 42550a5..003e427 100644
--- a/29WxOrderWpf/Ctrls/PDDInvoice/ViewModels/PDDInvoiceViewModel.cs
+++ b/29WxOrderWpf/Ctrls/PDDInvoice/ViewModels/PDDInvoiceViewModel.cs
@@ -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 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;
+ }
}
\ No newline at end of file