diff --git a/PacticeSolution/MVVMDatabaseSample/App.xaml b/PacticeSolution/MVVMDatabaseSample/App.xaml
new file mode 100644
index 0000000..70fcec1
--- /dev/null
+++ b/PacticeSolution/MVVMDatabaseSample/App.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/PacticeSolution/MVVMDatabaseSample/App.xaml.cs b/PacticeSolution/MVVMDatabaseSample/App.xaml.cs
new file mode 100644
index 0000000..1586b49
--- /dev/null
+++ b/PacticeSolution/MVVMDatabaseSample/App.xaml.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace MVVMDatabaseSample
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+ }
+}
diff --git a/PacticeSolution/MVVMDatabaseSample/AssemblyInfo.cs b/PacticeSolution/MVVMDatabaseSample/AssemblyInfo.cs
new file mode 100644
index 0000000..8b5504e
--- /dev/null
+++ b/PacticeSolution/MVVMDatabaseSample/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/PacticeSolution/MVVMDatabaseSample/MVVMDatabaseSample.csproj b/PacticeSolution/MVVMDatabaseSample/MVVMDatabaseSample.csproj
new file mode 100644
index 0000000..3a4a13a
--- /dev/null
+++ b/PacticeSolution/MVVMDatabaseSample/MVVMDatabaseSample.csproj
@@ -0,0 +1,18 @@
+
+
+
+ WinExe
+ net6.0-windows
+ enable
+ true
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PacticeSolution/MVVMDatabaseSample/MainWindow.xaml b/PacticeSolution/MVVMDatabaseSample/MainWindow.xaml
new file mode 100644
index 0000000..58c1f57
--- /dev/null
+++ b/PacticeSolution/MVVMDatabaseSample/MainWindow.xaml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PacticeSolution/MVVMDatabaseSample/MainWindow.xaml.cs b/PacticeSolution/MVVMDatabaseSample/MainWindow.xaml.cs
new file mode 100644
index 0000000..839f250
--- /dev/null
+++ b/PacticeSolution/MVVMDatabaseSample/MainWindow.xaml.cs
@@ -0,0 +1,35 @@
+using MVVMDatabaseSample.Util;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace MVVMDatabaseSample
+{
+ ///
+ /// Interaction logic for MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ public MainWindow()
+ {
+ InitializeComponent();
+ InitInstance();
+ }
+
+ private void InitInstance()
+ {
+ SqlDBManager.Instance.ConnectionString = "Data Source=peacecloud.synology.me,21433;Initial Catalog=Study;User ID=study;Password=Study1234";
+ }
+ }
+}
diff --git a/PacticeSolution/MVVMDatabaseSample/Model/Student.cs b/PacticeSolution/MVVMDatabaseSample/Model/Student.cs
new file mode 100644
index 0000000..d01a5f9
--- /dev/null
+++ b/PacticeSolution/MVVMDatabaseSample/Model/Student.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MVVMDatabaseSample.Model
+{
+ internal class Student
+ {
+ public string Name { get; set; }
+ public int Age { get; set; }
+ public string Grade { get; set; }
+ public int Score { get; set; }
+ }
+}
diff --git a/PacticeSolution/MVVMDatabaseSample/Util/SqlDBManager.cs b/PacticeSolution/MVVMDatabaseSample/Util/SqlDBManager.cs
new file mode 100644
index 0000000..e2c0e57
--- /dev/null
+++ b/PacticeSolution/MVVMDatabaseSample/Util/SqlDBManager.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Data.SqlClient;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MVVMDatabaseSample.Util
+{
+ internal sealed class SqlDBManager
+ {
+ public static SqlDBManager Instance { get; private set; } = new SqlDBManager();
+
+ public string ConnectionString { get; set; }
+
+ public SqlConnection Connection { get; private set; }
+
+ private SqlCommand _sqlCommand;
+
+ public bool GetConnection()
+ {
+ try
+ {
+ _sqlCommand = new SqlCommand();
+ _sqlCommand.Connection = this.Connection;
+
+ this.Connection = new SqlConnection(ConnectionString);
+ this.Connection.Open();
+
+ return true;
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ }
+
+ public DataSet ExecuteQuery(DataSet ds, string query)
+ {
+ ds.Reset();
+ lock (this)
+ {
+ SqlDataAdapter adapter = new SqlDataAdapter();
+ adapter.SelectCommand = _sqlCommand;
+ adapter.SelectCommand.Connection = this.Connection;
+ adapter.SelectCommand.CommandText = query;
+ adapter.Fill(ds);
+ }
+
+ return ds;
+ }
+ }
+}
diff --git a/PacticeSolution/MVVMDatabaseSample/ViewModel/DelegateCommand.cs b/PacticeSolution/MVVMDatabaseSample/ViewModel/DelegateCommand.cs
new file mode 100644
index 0000000..0b884df
--- /dev/null
+++ b/PacticeSolution/MVVMDatabaseSample/ViewModel/DelegateCommand.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Input;
+
+namespace MVVMDatabaseSample.ViewModel
+{
+ internal class DelegateCommand : ICommand
+ {
+ private readonly Func _canExecute;
+ private readonly Action _execute;
+
+ public event EventHandler? CanExecuteChanged;
+
+ public DelegateCommand(Action execute, Func canExecute)
+ {
+ _execute = execute;
+ _canExecute = canExecute;
+ }
+
+ public DelegateCommand(Action execute) : this(execute, null)
+ {
+
+ }
+
+ public bool CanExecute(object? parameter)
+ {
+ if (_canExecute == null)
+ return true;
+
+ return _canExecute();
+ }
+
+ public void Execute(object? parameter)
+ {
+ _execute();
+ }
+
+ public void RaiseCanExecuteChanged()
+ {
+ if (this.CanExecuteChanged != null)
+ this.CanExecuteChanged(this, EventArgs.Empty);
+ }
+ }
+}
diff --git a/PacticeSolution/MVVMDatabaseSample/ViewModel/ViewModelMain.cs b/PacticeSolution/MVVMDatabaseSample/ViewModel/ViewModelMain.cs
new file mode 100644
index 0000000..4b5aafd
--- /dev/null
+++ b/PacticeSolution/MVVMDatabaseSample/ViewModel/ViewModelMain.cs
@@ -0,0 +1,160 @@
+using MVVMDatabaseSample.Model;
+using MVVMDatabaseSample.Util;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls.Primitives;
+using System.Windows.Input;
+
+namespace MVVMDatabaseSample.ViewModel
+{
+ internal class ViewModelMain : INotifyPropertyChanged
+ {
+ private Student _student = new Student();
+ private ObservableCollection _sampleData;
+ private ICommand _connectCommand;
+ private ICommand _selectCommand;
+ private ICommand _loadedCommand;
+
+ public event PropertyChangedEventHandler? PropertyChanged;
+
+ public string Name
+ {
+ get { return _student.Name; }
+ set
+ {
+ _student.Name = value;
+ OnPropertyChanged("Name");
+ }
+ }
+
+ public int Age
+ {
+ get { return _student.Age; }
+ set
+ {
+ _student.Age = value;
+ OnPropertyChanged("Age");
+ }
+ }
+
+ public string Grage
+ {
+ get { return _student.Grade; }
+ set
+ {
+ _student.Grade = value;
+ OnPropertyChanged("Grade");
+ }
+ }
+
+ public int Score
+ {
+ get { return _student.Score; }
+ set
+ {
+ _student.Score = value;
+ OnPropertyChanged("Score");
+ }
+ }
+
+ public ObservableCollection SampleData
+ {
+ get
+ {
+ if (_sampleData == null)
+ _sampleData = new ObservableCollection();
+
+ return _sampleData;
+ }
+ set { _sampleData = value; }
+ }
+
+ public ICommand ConnectCommand
+ {
+ get
+ {
+ if (_connectCommand == null)
+ _connectCommand = new DelegateCommand(Connect);
+
+ return _connectCommand;
+ }
+ }
+
+ public ICommand SelectCommand
+ {
+ get
+ {
+ if (_selectCommand == null)
+ _selectCommand = new DelegateCommand(Select);
+
+ return _selectCommand;
+ }
+ }
+
+ public ICommand LoadedCommand
+ {
+ get
+ {
+ if (_loadedCommand == null)
+ _loadedCommand = new DelegateCommand(Load);
+
+ return _loadedCommand;
+ }
+ }
+
+ private void Connect()
+ {
+ string message;
+ if (!SqlDBManager.Instance.GetConnection())
+ message = "Fail to connect";
+ else
+ message = "Success to connect";
+
+ MessageBox.Show(message);
+ }
+
+ private void Select()
+ {
+ DataSet ds = new DataSet();
+ string qry = "SELECT * FROM Student";
+ SqlDBManager.Instance.ExecuteQuery(ds, qry);
+ if (ds.Tables.Count < 1)
+ return;
+
+ foreach (DataRow row in ds.Tables[0].Rows)
+ {
+ Student student = new Student()
+ {
+ Name = row["Name"].ToString(),
+ Age = (int)row["Age"],
+ Grade = row["Grade"].ToString(),
+ Score = (int)row["Score"],
+ };
+ _sampleData.Add(student);
+ }
+ }
+
+ private void Load()
+ {
+ string message;
+ if (!SqlDBManager.Instance.GetConnection())
+ message = "Fail to connect";
+ else
+ message = "Success to connect";
+
+ MessageBox.Show(message);
+ }
+
+ protected void OnPropertyChanged(string propertyName)
+ {
+ this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+}
diff --git a/PacticeSolution/PacticeSolution.sln b/PacticeSolution/PacticeSolution.sln
index 2e29af9..bf40cb8 100644
--- a/PacticeSolution/PacticeSolution.sln
+++ b/PacticeSolution/PacticeSolution.sln
@@ -15,6 +15,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MVVMSample", "MVVMSample\MV
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceSample", "ResourceSample\ResourceSample.csproj", "{858EC308-9ABD-44C1-92E1-59911F60FEB9}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MVVMDatabaseSample", "MVVMDatabaseSample\MVVMDatabaseSample.csproj", "{B0A8E6DE-C6A2-488E-A148-9E7812F615F2}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -45,6 +47,10 @@ Global
{858EC308-9ABD-44C1-92E1-59911F60FEB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{858EC308-9ABD-44C1-92E1-59911F60FEB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{858EC308-9ABD-44C1-92E1-59911F60FEB9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B0A8E6DE-C6A2-488E-A148-9E7812F615F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B0A8E6DE-C6A2-488E-A148-9E7812F615F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B0A8E6DE-C6A2-488E-A148-9E7812F615F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B0A8E6DE-C6A2-488E-A148-9E7812F615F2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/PacticeSolution/ResourceSample/MainWindow.xaml.cs b/PacticeSolution/ResourceSample/MainWindow.xaml.cs
index 0651521..25e50f5 100644
--- a/PacticeSolution/ResourceSample/MainWindow.xaml.cs
+++ b/PacticeSolution/ResourceSample/MainWindow.xaml.cs
@@ -31,7 +31,7 @@ namespace ResourceSample
if (_clickCount % 2 == 0)
this.Resources["CustomEventColor"] = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#3de385"));
else
- this.Resources["CustomEventColor"] = Resources["CustomRed"];
+ this.Resources["CustomEventColor"] = Application.Current.FindResource("CustomRed");
_clickCount++;
}