address book using mvvm

main
syneffort 2 years ago
parent fffd85ecb5
commit 3d9f030ebb
  1. 3
      PacticeSolution/AddressBook_MVVMSample/MainWindow.xaml.cs
  2. 2
      PacticeSolution/AddressBook_MVVMSample/SubWindow/AddViewWindow.xaml
  3. 14
      PacticeSolution/AddressBook_MVVMSampleV2/AddressBook_MVVMSampleV2.csproj
  4. 8
      PacticeSolution/AddressBook_MVVMSampleV2/App.xaml
  5. 42
      PacticeSolution/AddressBook_MVVMSampleV2/App.xaml.cs
  6. 10
      PacticeSolution/AddressBook_MVVMSampleV2/AssemblyInfo.cs
  7. 16
      PacticeSolution/AddressBook_MVVMSampleV2/Interface/IDialogView.cs
  8. 17
      PacticeSolution/AddressBook_MVVMSampleV2/Interface/IMessageBoxService.cs
  9. 16
      PacticeSolution/AddressBook_MVVMSampleV2/Interface/IWindowView.cs
  10. 12
      PacticeSolution/AddressBook_MVVMSampleV2/MainWindow.xaml
  11. 28
      PacticeSolution/AddressBook_MVVMSampleV2/MainWindow.xaml.cs
  12. 53
      PacticeSolution/AddressBook_MVVMSampleV2/Model/Person.cs
  13. 28
      PacticeSolution/AddressBook_MVVMSampleV2/Service/MessageBoxService.cs
  14. 65
      PacticeSolution/AddressBook_MVVMSampleV2/View/AddView.xaml
  15. 31
      PacticeSolution/AddressBook_MVVMSampleV2/View/AddView.xaml.cs
  16. 54
      PacticeSolution/AddressBook_MVVMSampleV2/View/MainView.xaml
  17. 31
      PacticeSolution/AddressBook_MVVMSampleV2/View/MainView.xaml.cs
  18. 67
      PacticeSolution/AddressBook_MVVMSampleV2/ViewModel/AddViewModel.cs
  19. 109
      PacticeSolution/AddressBook_MVVMSampleV2/ViewModel/MainViewModel.cs
  20. 6
      PacticeSolution/PacticeSolution.sln

@ -104,8 +104,7 @@ namespace AddressBook_MVVMSample
if (modify.ShowDialog() != true)
return;
//this.Persons[this.SelectedIndex] = modifiedData;
selectedData = modifiedData;
this.Persons[this.SelectedIndex] = modifiedData;
}
private void CommandExitAction(object obj)

@ -6,7 +6,7 @@
xmlns:local="clr-namespace:AddressBook_MVVMSample.SubWindow"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:AddViewWindow}"
Title="{Binding Caption, UpdateSourceTrigger=PropertyChanged}" Height="300" Width="300"
Title="{Binding Caption, UpdateSourceTrigger=PropertyChanged}" Height="300" Width="320"
WindowStartupLocation="CenterOwner">
<!--<Window.DataContext>
<local:AddViewWindow/>

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ReactiveUI.WPF" Version="19.4.1" />
</ItemGroup>
</Project>

@ -0,0 +1,8 @@
<Application x:Class="AddressBook_MVVMSampleV2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:AddressBook_MVVMSampleV2">
<Application.Resources>
</Application.Resources>
</Application>

@ -0,0 +1,42 @@
using AddressBook_MVVMSampleV2.Interface;
using AddressBook_MVVMSampleV2.Model;
using AddressBook_MVVMSampleV2.Service;
using AddressBook_MVVMSampleV2.View;
using AddressBook_MVVMSampleV2.ViewModel;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace AddressBook_MVVMSampleV2
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
IMessageBoxService messageBoxService = new MessageBoxService();
MainViewModel mainViewModel = new MainViewModel(messageBoxService, CreateAddView);
MainView mainView = new MainView(mainViewModel);
mainView.Show();
}
private IDialogView CreateAddView(Person modifyData, AddViewModel.ViewType type = AddViewModel.ViewType.Add)
{
AddViewModel viewModel = new AddViewModel(modifyData, type);
return new AddView(viewModel);
}
protected override void OnExit(ExitEventArgs e)
{
base.OnExit(e);
}
}
}

@ -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)
)]

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AddressBook_MVVMSampleV2.Interface
{
public interface IDialogView
{
bool? ShowDialog();
bool? DialogResult { get; set; }
void Show();
void Close();
}
}

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace AddressBook_MVVMSampleV2.Interface
{
public interface IMessageBoxService
{
MessageBoxResult Show(string message);
MessageBoxResult Show(string message, string caption);
MessageBoxResult Show(string message, string caption, MessageBoxButton button, MessageBoxImage icon);
}
}

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace AddressBook_MVVMSampleV2.Interface
{
internal interface IWindowView
{
void Show();
void Close();
Visibility Visibility { get; set; }
}
}

@ -0,0 +1,12 @@
<Window x:Class="AddressBook_MVVMSampleV2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AddressBook_MVVMSampleV2"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>

@ -0,0 +1,28 @@
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 AddressBook_MVVMSampleV2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}

@ -0,0 +1,53 @@
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AddressBook_MVVMSampleV2.Model
{
public class Person : ReactiveObject
{
public Person()
{
}
public Person(Person input)
{
_name = input.Name;
_gender = input.Gender;
_phoneNumber = input.PhoneNumber;
_address = input.Address;
}
private string _name;
public string Name
{
get { return _name; }
set { this.RaiseAndSetIfChanged(ref _name, value); }
}
private bool _gender;
public bool Gender
{
get { return _gender; }
set { this.RaiseAndSetIfChanged(ref _gender, value); }
}
private string _phoneNumber;
public string PhoneNumber
{
get { return _phoneNumber; }
set { this.RaiseAndSetIfChanged(ref _phoneNumber, value); }
}
private string _address;
public string Address
{
get { return _address; }
set { this.RaiseAndSetIfChanged(ref _address, value); }
}
}
}

@ -0,0 +1,28 @@
using AddressBook_MVVMSampleV2.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace AddressBook_MVVMSampleV2.Service
{
internal class MessageBoxService : IMessageBoxService
{
public MessageBoxResult Show(string message)
{
return MessageBox.Show(message);
}
public MessageBoxResult Show(string message, string caption)
{
return MessageBox.Show(message, caption);
}
public MessageBoxResult Show(string message, string caption, MessageBoxButton button, MessageBoxImage icon)
{
return MessageBox.Show(message, caption, button, icon);
}
}
}

@ -0,0 +1,65 @@
<Window x:Name="winAddView"
x:Class="AddressBook_MVVMSampleV2.View.AddView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AddressBook_MVVMSampleV2.View"
xmlns:vm="clr-namespace:AddressBook_MVVMSampleV2.ViewModel"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance vm:AddViewModel}"
Title="{Binding Caption, UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
WindowStartupLocation="CenterScreen"
WindowStyle="ToolWindow"
Height="300" Width="300">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" VerticalAlignment="Center" Margin="3"
Content="Name"/>
<TextBox Grid.Column="1" Grid.Row="0" Margin="3"
TextWrapping="Wrap"
Text="{Binding PersonData.Name, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
<Label Grid.Column="0" Grid.Row="1" VerticalAlignment="Center" Margin="3"
Content="Gender"/>
<TextBox Grid.Column="1" Grid.Row="1" Margin="3"
TextWrapping="Wrap"
Text="{Binding PersonData.Gender, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
<Label Grid.Column="0" Grid.Row="2" VerticalAlignment="Center" Margin="3"
Content="Phone"/>
<TextBox Grid.Column="1" Grid.Row="2" Margin="3"
TextWrapping="Wrap"
Text="{Binding PersonData.PhoneNumber, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
<Label Grid.Column="0" Grid.Row="3" VerticalAlignment="Center" Margin="3"
Content="Address"/>
<TextBox Grid.Column="1" Grid.Row="3" Margin="3"
TextWrapping="Wrap"
Text="{Binding PersonData.Address, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
<StackPanel Grid.Column="1" Grid.Row="4" Orientation="Horizontal" HorizontalAlignment="Right" Margin="3">
<Button Width="70" Margin="3 0 0 0"
Content="OK"
IsDefault="True"
Command="{Binding OkCommand}"
CommandParameter="{Binding ElementName=winAddView}"/>
<Button Width="70" Margin="3 0 0 0"
Content="Cancel"
IsDefault="True"
Command="{Binding CancelCommand}"
CommandParameter="{Binding ElementName=winAddView}"/>
</StackPanel>
</Grid>
</Window>

@ -0,0 +1,31 @@
using AddressBook_MVVMSampleV2.Interface;
using AddressBook_MVVMSampleV2.ViewModel;
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.Shapes;
namespace AddressBook_MVVMSampleV2.View
{
/// <summary>
/// AddView.xaml에 대한 상호 작용 논리
/// </summary>
public partial class AddView : Window, IDialogView
{
public AddView(AddViewModel addViewModel)
{
InitializeComponent();
this.DataContext = addViewModel;
}
}
}

@ -0,0 +1,54 @@
<Window x:Name="winMain"
x:Class="AddressBook_MVVMSampleV2.View.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AddressBook_MVVMSampleV2.View"
xmlns:vm="clr-namespace:AddressBook_MVVMSampleV2.ViewModel"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance vm:MainViewModel}"
Title="Address Book" Height="350" Width="600"
WindowStartupLocation="CenterScreen">
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<DataGrid x:Name="grdPersons" Grid.Row="0"
SelectionMode="Single" AutoGenerateColumns="False" IsReadOnly="True"
AlternationCount="2" AlternatingRowBackground="LightSalmon"
ItemsSource="{Binding Persons, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<DataGrid.InputBindings>
<MouseBinding Gesture="LeftDoubleClick"
Command="{Binding ModifyCommand}"
CommandParameter="{Binding ElementName=grdPersons, Path=SelectedIndex}"/>
</DataGrid.InputBindings>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="100"
Binding="{Binding Name}"/>
<DataGridTextColumn Header="Gender"
Binding="{Binding Gender}"/>
<DataGridTextColumn Header="Phone number" Width="100"
Binding="{Binding PhoneNumber}"/>
<DataGridTextColumn Header="Address" Width="200"
Binding="{Binding Address}"/>
</DataGrid.Columns>
</DataGrid>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="Add" Width="100" Margin="3"
Command="{Binding AddCommand}"/>
<Button Content="Modify" Width="100" Margin="3"
Command="{Binding ModifyCommand}"
CommandParameter="{Binding ElementName=grdPersons, Path=SelectedIndex}"/>
<Button Content="Delete" Width="100" Margin="3"
Command="{Binding DeleteCommand}"
CommandParameter="{Binding ElementName=grdPersons, Path=SelectedIndex}"/>
<Button Content="Exit" Width="100" Margin="3"
Command="{Binding ExitCommand}"
CommandParameter="{Binding ElementName=winMain}"/>
</StackPanel>
</Grid>
</Window>

@ -0,0 +1,31 @@
using AddressBook_MVVMSampleV2.Interface;
using AddressBook_MVVMSampleV2.ViewModel;
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.Shapes;
namespace AddressBook_MVVMSampleV2.View
{
/// <summary>
/// MainView.xaml에 대한 상호 작용 논리
/// </summary>
public partial class MainView : Window, IWindowView
{
public MainView(MainViewModel viewModel)
{
InitializeComponent();
this.DataContext = viewModel;
}
}
}

@ -0,0 +1,67 @@
using AddressBook_MVVMSampleV2.Interface;
using AddressBook_MVVMSampleV2.Model;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace AddressBook_MVVMSampleV2.ViewModel
{
public class AddViewModel : ReactiveObject
{
public enum ViewType
{
Add,
Modify
}
public Person PersonData { get; set; }
public ICommand OkCommand { get; private set; }
public ICommand CancelCommand { get; private set; }
public AddViewModel() : this(null, ViewType.Add)
{
}
public AddViewModel(Person data = null, ViewType type = ViewType.Add)
{
if (type == ViewType.Modify)
this.Caption = "Modifty information";
else
this.Caption = "Add infomation";
this.PersonData = data;
this.OkCommand = ReactiveCommand.Create<IDialogView, Unit>(view => FuncOkCommand(view));
this.CancelCommand = ReactiveCommand.Create<IDialogView, Unit>(view => FuncCancelCommand(view));
}
private string _caption;
public string Caption
{
get { return _caption; }
set { this.RaiseAndSetIfChanged(ref _caption, value); }
}
private Unit FuncOkCommand(IDialogView view)
{
view.DialogResult = true;
view.Close();
return Unit.Default;
}
private Unit FuncCancelCommand(IDialogView view)
{
view.DialogResult = false;
view.Close();
return Unit.Default;
}
}
}

@ -0,0 +1,109 @@
using AddressBook_MVVMSampleV2.Interface;
using AddressBook_MVVMSampleV2.Model;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace AddressBook_MVVMSampleV2.ViewModel
{
public class MainViewModel : ReactiveObject
{
public ObservableCollection<Person> Persons { get; set; }
public ICommand AddCommand { get; set; }
public ICommand DeleteCommand { get; set; }
public ICommand ModifyCommand { get; set; }
public ICommand ExitCommand { get; set; }
private readonly IMessageBoxService MessageBoxService;
private readonly Func<Person, AddViewModel.ViewType, IDialogView> CreateAddView;
public MainViewModel() : this(null, null)
{
}
public MainViewModel(IMessageBoxService messageBoxService, Func<Person, AddViewModel.ViewType, IDialogView> createAddView)
{
this.MessageBoxService = messageBoxService;
this.CreateAddView = createAddView;
this.Persons = new ObservableCollection<Person>();
InitInstance();
}
private void InitInstance()
{
// Init Commands
this.AddCommand = ReactiveCommand.Create<Unit>(CommandAdd);
this.ModifyCommand = ReactiveCommand.Create<int, Unit>(index => CommandModify(index));
this.DeleteCommand = ReactiveCommand.Create<int, Unit>(index => CommandDelete(index));
this.ExitCommand = ReactiveCommand.Create<IWindowView, Unit>(view => CommandExit(view));
// Init Default Data
this.Persons.Add(new Person() { Name = "Kim", Gender = true, PhoneNumber = "123-4567", Address = "KOR" });
this.Persons.Add(new Person() { Name = "Max", Gender = true, PhoneNumber = "123-4567", Address = "USA" });
this.Persons.Add(new Person() { Name = "John", Gender = true, PhoneNumber = "123-4567", Address = "UK" });
this.Persons.Add(new Person() { Name = "Richard", Gender = true, PhoneNumber = "123-4567", Address = "UK" });
this.Persons.Add(new Person() { Name = "Shinoda", Gender = true, PhoneNumber = "123-4567", Address = "JPN" });
}
private Unit CommandAdd()
{
Person addData = new Person();
IDialogView view = this.CreateAddView(addData, AddViewModel.ViewType.Add);
if (view.ShowDialog() != true)
return Unit.Default;
this.Persons.Add(addData);
return Unit.Default;
}
private Unit CommandDelete(int selectedIndex)
{
if (selectedIndex < 0)
{
this.MessageBoxService.Show("No selected data.", "AddressBook", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
return Unit.Default;
}
MessageBoxResult result = this.MessageBoxService.Show("Are you sure to delete?", "AddressBook", MessageBoxButton.OKCancel, MessageBoxImage.Question);
if (result != MessageBoxResult.OK)
return Unit.Default;
this.Persons.RemoveAt(selectedIndex);
return Unit.Default;
}
private Unit CommandModify(int selectedIndex)
{
if (selectedIndex < 0)
{
this.MessageBoxService.Show("No selected data.", "AddressBook", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
return Unit.Default;
}
Person modifyData = new Person(this.Persons[selectedIndex]);
IDialogView view = this.CreateAddView(modifyData, AddViewModel.ViewType.Modify);
if (view.ShowDialog() != true)
return Unit.Default;
this.Persons[selectedIndex] = modifyData;
return Unit.Default;
}
private Unit CommandExit(IWindowView view)
{
view.Close();
return Unit.Default;
}
}
}

@ -89,6 +89,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DashedFigure", "DashedFigur
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddressBook_MVVMSample", "AddressBook_MVVMSample\AddressBook_MVVMSample.csproj", "{6A452509-3DEB-41A3-8AA3-8DB4BE948D28}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddressBook_MVVMSampleV2", "AddressBook_MVVMSampleV2\AddressBook_MVVMSampleV2.csproj", "{0CE2A390-5A8B-4F13-9F60-A4AF77F0B1F3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -267,6 +269,10 @@ Global
{6A452509-3DEB-41A3-8AA3-8DB4BE948D28}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6A452509-3DEB-41A3-8AA3-8DB4BE948D28}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6A452509-3DEB-41A3-8AA3-8DB4BE948D28}.Release|Any CPU.Build.0 = Release|Any CPU
{0CE2A390-5A8B-4F13-9F60-A4AF77F0B1F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CE2A390-5A8B-4F13-9F60-A4AF77F0B1F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CE2A390-5A8B-4F13-9F60-A4AF77F0B1F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CE2A390-5A8B-4F13-9F60-A4AF77F0B1F3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Loading…
Cancel
Save