mvvm event driven

main
syneffort 1 year ago
parent 75410991fe
commit 3d216dfe83
  1. 35
      MVVMwithWPF/MVVMwithWPF/Converters/BoolToVisibilityConverter.cs
  2. 28
      MVVMwithWPF/MVVMwithWPF/Models/Member.cs
  3. 135
      MVVMwithWPF/MVVMwithWPF/ViewModels/MainViewModel.cs
  4. 8
      MVVMwithWPF/MVVMwithWPF/ViewModels/ViewModelBase.cs
  5. 132
      MVVMwithWPF/MVVMwithWPF/Views/MainWindow.xaml

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
namespace MVVMwithWPF.Converters
{
internal class BoolToVisibilityConverter : IValueConverter
{
public Visibility TrueVlaue { get; set; } = Visibility.Visible;
public Visibility FalseValue { get; set; } = Visibility.Collapsed;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool boolVlaue)
{
if (boolVlaue)
return TrueVlaue;
else
return FalseValue;
}
return Binding.DoNothing;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

@ -0,0 +1,28 @@
using CommunityToolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MVVMwithWPF.Models
{
internal partial class Member : ObservableObject, ICloneable
{
public int Id { get; set; }
public DateTime RegDate { get; set; }
[ObservableProperty]
private string _name;
[ObservableProperty]
private string _phone;
[ObservableProperty]
private bool _isUse;
public object Clone()
{
return MemberwiseClone();
}
}
}

@ -1,16 +1,147 @@
using System;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using MVVMwithWPF.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace MVVMwithWPF.ViewModels
{
internal class MainViewModel : ViewModelBase
internal partial class MainViewModel : ViewModelBase
{
[ObservableProperty]
private ObservableCollection<Member> _members;
[ObservableProperty]
private bool _isEditing;
[ObservableProperty]
private Member _editMember;
private bool CanEditMember { get { return EditMember != null; } }
public MainViewModel()
{
Title = "Main View";
Init();
}
private void Init()
{
Members = new ObservableCollection<Member>();
{
new Member()
{
Id = 1,
Name = "member001",
Phone = "010-1234-5678",
RegDate = DateTime.Now,
IsUse = true
};
};
PropertyChanged += MainViewModel_PropertyChanged;
}
[RelayCommand]
private void Save()
{
IsEditing = false;
if (EditMember.Id == 0)
{
var id = Members.Any() ? Members.Max(m => m.Id) + 1 : 1;
EditMember.Id = id;
EditMember.RegDate = DateTime.Now;
Members.Add((Member)EditMember.Clone());
EditMember = null;
}
else
{
var member = Members.FirstOrDefault(m => m.Id == EditMember.Id);
if (member == null)
return;
member.Name = EditMember.Name;
member.Phone = EditMember.Phone;
member.IsUse = EditMember.IsUse;
}
}
[RelayCommand]
private void Cancle()
{
IsEditing = false;
EditMember = null;
}
[RelayCommand(CanExecute = nameof(CanEditMember))]
private void Delete()
{
if (EditMember == null)
return;
var result = MessageBox.Show("선택된 아이템을 삭제하시겠습니까?", "확인", MessageBoxButton.YesNo);
if (result != MessageBoxResult.Yes)
return;
IsEditing = false;
var removeMember = Members.FirstOrDefault(m => m.Id == EditMember.Id);
if (removeMember != null)
Members.Remove(removeMember);
EditMember = null;
}
[RelayCommand]
private void New()
{
IsEditing = true;
EditMember = new Member
{
IsUse = true
};
}
[RelayCommand(CanExecute = nameof(CanEditMember))]
private void Edit()
{
IsEditing = true;
}
[RelayCommand]
private void SelectionChanged(object param)
{
var args = param as SelectionChangedEventArgs;
if (args == null)
return;
if (args.AddedItems.Count < 1)
{
EditMember = null;
return;
}
if (args.AddedItems[0] is Member member)
EditMember = (Member)member.Clone();
}
private void MainViewModel_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
switch(e.PropertyName)
{
case nameof(EditMember):
EditCommand.NotifyCanExecuteChanged();
DeleteCommand.NotifyCanExecuteChanged();
break;
}
}
}
}

@ -7,13 +7,9 @@ using System.Threading.Tasks;
namespace MVVMwithWPF.ViewModels
{
internal abstract class ViewModelBase : ObservableObject
internal abstract partial class ViewModelBase : ObservableObject
{
[ObservableProperty]
private string _title;
public string Title
{
get => _title;
set => SetProperty(ref _title, value);
}
}
}

@ -1,6 +1,8 @@
<Window x:Class="MVVMwithWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
xmlns:converters="clr-namespace:MVVMwithWPF.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MVVMwithWPF"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
@ -11,6 +13,12 @@
d:DataContext="{d:DesignInstance Type=viewModels:MainViewModel,
IsDesignTimeCreatable=True}"
mc:Ignorable="d">
<Window.Resources>
<converters:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<converters:BoolToVisibilityConverter x:Key="ReverseBoolToVisibilityConverter"
FalseValue="Visible" TrueVlaue="Collapsed" />
</Window.Resources>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
@ -21,5 +29,129 @@
<MenuItem Header="_Exit" />
</MenuItem>
</Menu>
<Grid DockPanel.Dock="Bottom">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Button Width="80"
HorizontalAlignment="Right"
Content="Serch" />
<DataGrid x:Name="dgrMember"
Grid.Row="1"
Margin="0,10,0,0"
AutoGenerateColumns="False" IsReadOnly="True"
ItemsSource="{Binding Members}">
<b:Interaction.Triggers>
<b:EventTrigger EventName="SelectionChanged">
<b:InvokeCommandAction Command="{Binding SelectionChangedCommand}" PassEventArgsToCommand="True" />
</b:EventTrigger>
</b:Interaction.Triggers>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Id}" Header="Id" />
<DataGridTextColumn Binding="{Binding Name}" Header="Name" />
<DataGridTextColumn Binding="{Binding Phone}" Header="Phone" />
<DataGridTextColumn Binding="{Binding RegDate}" Header="Registered Date" />
<DataGridTextColumn Binding="{Binding IsUse}" Header="Use" />
</DataGrid.Columns>
</DataGrid>
<StackPanel Grid.Column="1"
Margin="0,0,5,0" HorizontalAlignment="Right"
Orientation="Horizontal">
<Button x:Name="btnNew"
Width="80"
Command="{Binding NewCommand}"
Content="New"
Visibility="{Binding IsEditing, Converter={StaticResource ReverseBoolToVisibilityConverter}}" />
<Button x:Name="btnEdit"
Width="80"
Command="{Binding EditCommand}"
Content="Edit"
Visibility="{Binding IsEditing, Converter={StaticResource ReverseBoolToVisibilityConverter}}" />
<Button x:Name="btnDelete"
Width="80"
Command="{Binding DeleteCommand}"
Content="Delete"
Visibility="{Binding IsEditing, Converter={StaticResource ReverseBoolToVisibilityConverter}}" />
<Button x:Name="btnSave"
Width="80"
Command="{Binding SaveCommand}"
Content="Save"
Visibility="{Binding IsEditing, Converter={StaticResource BoolToVisibilityConverter}}" />
<Button x:Name="btnCancel"
Width="80"
Command="{Binding CancleCommand}"
Content="Cancel"
Visibility="{Binding IsEditing, Converter={StaticResource BoolToVisibilityConverter}}" />
</StackPanel>
<Grid x:Name="grdDetail"
Grid.Row="1" Grid.Column="1"
Margin="0,10,0,0"
IsEnabled="{Binding IsEditing}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="7*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Margin="4" Background="Gray">
<TextBlock Margin="4,0,0,0"
Foreground="White" Text="Id" />
</Border>
<TextBlock x:Name="id"
Grid.Column="1"
Margin="4"
Text="{Binding EditMember.Id}" />
<Border Grid.Row="1"
Margin="4"
Background="Gray">
<TextBlock Margin="4,0,0,0"
Foreground="White" Text="Name" />
</Border>
<TextBox x:Name="name"
Grid.Row="1" Grid.Column="1"
Margin="4"
Text="{Binding EditMember.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Border Grid.Row="2"
Margin="4"
Background="Gray">
<TextBlock Margin="4,0,0,0"
Foreground="White" Text="Phone" />
</Border>
<TextBox x:Name="phone"
Grid.Row="2" Grid.Column="1"
Margin="4"
Text="{Binding EditMember.Phone, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<Border Grid.Row="3"
Margin="4"
Background="Gray">
<TextBlock Margin="4,0,0,0"
Foreground="White" Text="Registered Date" />
</Border>
<TextBlock x:Name="regDate"
Grid.Row="3" Grid.Column="1"
Margin="4"
Text="{Binding EditMember.RegDate, StringFormat={}{0:d}}" />
<Border Grid.Row="4"
Margin="4"
Background="Gray">
<TextBlock Margin="4,0,0,0"
Foreground="White" Text="Use" />
</Border>
<CheckBox x:Name="isUse"
Grid.Row="4" Grid.Column="1"
Margin="4"
IsChecked="{Binding EditMember.IsUse, Mode=TwoWay}" />
</Grid>
</Grid>
</DockPanel>
</Window>

Loading…
Cancel
Save