diff --git a/App.xaml b/App.xaml
new file mode 100644
index 0000000..e7e5ec2
--- /dev/null
+++ b/App.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/App.xaml.cs b/App.xaml.cs
new file mode 100644
index 0000000..632f4a7
--- /dev/null
+++ b/App.xaml.cs
@@ -0,0 +1,13 @@
+using System.Configuration;
+using System.Data;
+using System.Windows;
+
+namespace YwxApp.AiChat;
+
+///
+/// Interaction logic for App.xaml
+///
+public partial class App : Application
+{
+}
+
diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs
new file mode 100644
index 0000000..cc29e7f
--- /dev/null
+++ b/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly:ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/Commands/ClosingWindowBehavior.cs b/Commands/ClosingWindowBehavior.cs
new file mode 100644
index 0000000..eaa2dd7
--- /dev/null
+++ b/Commands/ClosingWindowBehavior.cs
@@ -0,0 +1,54 @@
+
+using System.ComponentModel;
+using System.Windows;
+using System.Windows.Input;
+using System.Windows.Interactivity;
+namespace YwxApp.AiChat.Commands
+{
+
+
+ ///
+ /// Close Window Behavior
+ ///
+ public class ClosingWindowBehavior : Behavior
+ {
+ public static readonly DependencyProperty CommandProperty =
+ DependencyProperty.Register("Command", typeof(ICommand), typeof(ClosingWindowBehavior), new PropertyMetadata(null));
+
+ public static readonly DependencyProperty CommandParameterProperty =
+ DependencyProperty.Register("CommandParameter", typeof(object), typeof(ClosingWindowBehavior), new PropertyMetadata(null));
+
+ public ICommand Command
+ {
+ get { return (ICommand)GetValue(CommandProperty); }
+ set { SetValue(CommandProperty, value); }
+ }
+
+ public object CommandParameter
+ {
+ get { return GetValue(CommandParameterProperty); }
+ set { SetValue(CommandParameterProperty, value); }
+ }
+
+ protected override void OnAttached()
+ {
+ base.OnAttached();
+ AssociatedObject.Closing += OnClosing;
+ }
+
+ protected override void OnDetaching()
+ {
+ base.OnDetaching();
+ AssociatedObject.Closing -= OnClosing;
+ }
+
+ private void OnClosing(object sender, CancelEventArgs e)
+ {
+ if (Command != null && Command.CanExecute(CommandParameter))
+ {
+ Command.Execute(e);
+ }
+ }
+ }
+ }
+
diff --git a/Commands/EventsCommand.cs b/Commands/EventsCommand.cs
new file mode 100644
index 0000000..45a538b
--- /dev/null
+++ b/Commands/EventsCommand.cs
@@ -0,0 +1,29 @@
+using System.Windows.Input;
+
+namespace YwxApp.AiChat.Commands
+{
+
+ public class EventsCommand : ICommand
+ {
+ private readonly Action _execute;
+ private readonly Func _canExecute;
+ public EventsCommand(Action execute, Func canExecute = null)
+ {
+ _execute = execute ?? throw new ArgumentNullException(nameof(execute));
+ _canExecute = canExecute;
+ }
+ public bool CanExecute(object parameter)
+ {
+ return _canExecute?.Invoke((T)parameter) ?? true;
+ }
+ public void Execute(object parameter)
+ {
+ _execute((T)parameter);
+ }
+ public event EventHandler CanExecuteChanged
+ {
+ add { CommandManager.RequerySuggested += value; }
+ remove { CommandManager.RequerySuggested -= value; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Commands/ObjectPassingCommand.cs b/Commands/ObjectPassingCommand.cs
new file mode 100644
index 0000000..16350d9
--- /dev/null
+++ b/Commands/ObjectPassingCommand.cs
@@ -0,0 +1,29 @@
+using System.Windows.Input;
+
+namespace YwxApp.AiChat.Commands
+{
+
+ ///
+ /// object parameter passing.
+ ///
+ public class ObjectPassingCommand : ICommand
+ {
+ public Action