💻 Duty 클래스 (View Model에 해당)
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HelloWorld1
{
public enum DutyType // 열거형
{
Inner,
OutSide
}
public class Duty
{
private string _name; // 직무명
private DutyType _dutyType; // 직무타입(내근, 외근)
public Duty() { } // 생성자
public Duty(string name, DutyType dutyType)
{
_name = name;
_dutyType = dutyType;
}
// 프로퍼티
public string DutyName
{
get { return _name; }
set
{
_name= value;
}
}
public DutyType DutyType
{
get { return _dutyType; }
set
{
_dutyType = value;
}
}
}
public class Duties : ObservableCollection<Duty>
{
public Duties()
{
Add(new Duty("SALES", DutyType.OutSide));
Add(new Duty("LOGISTICS", DutyType.OutSide));
Add(new Duty("IT", DutyType.Inner));
Add(new Duty("MARKETING", DutyType.Inner));
Add(new Duty("HR", DutyType.Inner));
Add(new Duty("PROPOTION", DutyType.OutSide));
}
}
}
💻 MainWindow.xaml
<Window x:Class="HelloWorld1.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:HelloWorld1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<!--Duty파일에서 만든 Duties 클래스를 resource로 등록-->
<local:Duties x:Key="duties"/>
<DataTemplate x:Key="MyTemplate">
<Border x:Name="border">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Duty Name"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=DutyName}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Duty Type"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=DutyType}"/>
<Separator Grid.Row="2" Grid.ColumnSpan="2"/>
</Grid>
</Border>
</DataTemplate>
<LinearGradientBrush x:Key="GrayBlueGradienBrush" StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="DarkGray" Offset="0"/>
<GradientStop Color="#CCCCFF" Offset="0.5"/>
<GradientStop Color="DarkGray" Offset="1"/>
</LinearGradientBrush>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="{StaticResource GrayBlueGradienBrush}"/>
<Setter Property="Width" Value="80"/>
<Setter Property="Margin" Value="10"/>
</Style>
</Window.Resources>
<!--실제 UI-->
<StackPanel>
<Button x:Name="Add" Click="OpenNewWindow">직무 추가</Button>
<TextBlock Margin="10,0,0,0">직무타입을 선택 하세요.</TextBlock>
<ListBox Name="myListBox1"
SelectionChanged="OnSelected"
SelectedIndex="0"
Margin="10,0,10,0">
<ListBoxItem>Inner</ListBoxItem>
<ListBoxItem>OutSide</ListBoxItem>
</ListBox>
<TextBlock Margin="10,10,0,-10">직무</TextBlock>
<ListBox Width="400" Margin="10" Name="myListBox2"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource MyTemplate}"
SelectionChanged="OnSelected2"/>
</StackPanel>
</Window>
💻 MainWindow.xaml.cs
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 HelloWorld1
{
public partial class MainWindow : Window
{
internal static Duties duties = new Duties();
public MainWindow()
{
InitializeComponent();
}
private void OnSelected(object sender, SelectionChangedEventArgs e)
{
if((sender as ListBox).SelectedItem != null)
{
string dutyType = ((sender as ListBox).SelectedItem as ListBoxItem).Content.ToString();
DataContext = from duty in duties
where duty.DutyType.ToString() == dutyType
select duty;
// dutyType이 일치하는 dutyfmf duties에서 하나씩 꺼내서 select 한다
}
}
private void OnSelected2(object sender, SelectionChangedEventArgs e)
{
var duty = (Duty)myListBox2.SelectedItem;
//string value = duty == null ? "No Selection" : duty.ToString();
MessageBox.Show(duty.DutyName + "::" + duty.DutyType, "선택한 직무");
}
// 직무 추가 버튼을 클릭 했을 때 새 창을 띄움
private void OpenNewWindow(object sender, RoutedEventArgs e)
{
SubWindow subWindow = new SubWindow();
RefreshListEvent += new RefreshList(RefreshListBox);
subWindow.UpdateActor = RefreshListEvent;
subWindow.Show();
}
// 아래쪽 ListABox를 Refresh 하기 위한 델리게이트 및 이벤트
public delegate void RefreshList(DutyType dutyType);
public event RefreshList RefreshListEvent;
// RefreshListEvent 이벤트가 발생했을 때 호출되는 메서드
private void RefreshListBox(DutyType dutyType)
{
// 내근은 SelectedIndex를 0, 외근은 SelectedIndex를 1로 설정하여
// 상단 ListBox의 선택값을 변경 시킨다.
// 상단 ListBox의 값이 바뀜에 따라 OnSAelected 이벤트 핸들러가 호출되어
// 자동으로 아래쪽 ListBox의 값은 변경된다
myListBox1.SelectedItem = null;
myListBox2.SelectedIndex = (dutyType == DutyType.Inner ? 0 : 1);
}
}
}
💻 SubWindow.xaml
<Window x:Class="HelloWorld1.SubWindow"
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:HelloWorld1"
mc:Ignorable="d"
Title="SubWindow" Height="300" Width="300">
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<TextBlock FontSize="20" Grid.ColumnSpan="3" HorizontalAlignment="Center" VerticalAlignment="Center">직무 등록</TextBlock>
<TextBlock Grid.Row="1" Margin="10" VerticalAlignment="Center">직무명</TextBlock>
<TextBox x:Name="txtDutyName" Grid.Row="1" Margin="10" Grid.Column="1" Grid.ColumnSpan="2" VerticalAlignment="Center"/>
<TextBlock Margin="10" Grid.Row="2" VerticalAlignment="Center">직무타입</TextBlock>
<RadioButton x:Name="rdoInner" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center">내근</RadioButton>
<RadioButton x:Name="rdoOutside" Grid.Row="2" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center">외근</RadioButton>
<Button Grid.Column="1" Grid.Row="2" Width="100" HorizontalAlignment="Center" Click="Button_Click" Height="22" Margin="0,52,0,-34">저장</Button>
</Grid>
</Window>
💻 SubWindow.xaml.cs
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 HelloWorld1
{
public partial class SubWindow : Window
{
// 메인 윈도우의 하단 ListBox를 Refresh하기 위한 델리게이트
// 메인 윈도우에서 직무추가 버튼을 클릭할 때 이벤트를 할당해 준다.
public Delegate UpdateActor;
public SubWindow()
{
InitializeComponent();
}
// 저장 버튼 클릭
private void Button_Click(object sender, RoutedEventArgs e)
{
if (rdoInner.IsChecked == false && rdoOutside.IsChecked == false)
{
MessageBox.Show("내근 또는 외근을 선택하세요.", "항목선택");
return;
}
DutyType dutyType = (rdoInner.IsChecked == true) ? DutyType.Inner : DutyType.OutSide;
MainWindow.duties.Add(new Duty(txtDutyName.Text, dutyType));
// 델리게이트 호출
UpdateActor.DynamicInvoke(dutyType);
MessageBox.Show("저장OK!", "저장확인");
this.Close();
}
}
}
'C# > WPF' 카테고리의 다른 글
[WPF] 데이터 바인딩 (0) | 2023.08.07 |
---|---|
[WPF] 의존 프로퍼티(Dependency Property) / 의존 속성 (0) | 2023.08.06 |
[WPF] Data Trigger(데이터 트리거) (0) | 2023.08.05 |
[WPF] Trigger, Property Trigger(프로퍼티 트리거) (0) | 2023.08.04 |
[WPF] StaticResource (0) | 2023.08.04 |