7장. WPF ListBox와 LINQ쿼리를 이용한 간단한 데이터바인딩
- C#/WPF
- 2021. 5. 8. 18:04
7장. WPF ListBox와 LINQ쿼리를 이용한 간단한 데이터바인딩
참조
목적
- WPF ListBox와 LINQ 쿼리를 이용하여 간단한 데이터바인딩 실습을 해봅니다.
Duty.cs
using System.Collections.ObjectModel;
namespace WPF07_Test
{
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));
}
}
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;
}
}
}
}
MainWindow.xaml
<Window x:Class="WPF07_Test.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:WPF07_Test"
mc:Ignorable="d"
Title="MainWindow" Height="400" Width="450">
<Window.Resources>
<local:Duties x:Key="duites"/>
<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="GrayBlueGradientBrush"
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 GrayBlueGradientBrush}"/>
<Setter Property="Width" Value="80"/>
<Setter Property="Margin" Value="10"/>
</Style>
</Window.Resources>
<StackPanel>
<Button x:Name="Add" Click="Add_Click"
Content="직무 추가"/>
<TextBlock Margin="10 0 0 0"
Text="직무 타입을 선택 하세요."/>
<ListBox x:Name="myListBox1"
SelectionChanged="myListBox1_SelectionChanged"
SelectedIndex="0"
Margin="10 0 0 0">
<ListBoxItem>Inner</ListBoxItem>
<ListBoxItem>OutSide</ListBoxItem>
</ListBox>
<TextBlock Margin="10 10 0 -10"
Text="직무"/>
<ListBox x:Name="myListBox2"
Width="400" Margin="10"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource MyTemplate}"
SelectionChanged="myListBox2_SelectionChanged">
</ListBox>
</StackPanel>
</Window>
MainWindow.xaml.cs
using System.Linq;
using System.Windows;
using System.Windows.Controls;
namespace WPF07_Test
{
/// <summary>
/// MainWindow.xaml에 대한 상호 작용 논리
/// </summary>
public partial class MainWindow : Window
{
internal static Duties duties = new Duties();
// ListBox를 Refresh 하기 위한 Delegate 및 이벤트
public delegate void RefreshList(DutyType dutyType);
public event RefreshList RefreshListEvent;
public MainWindow()
{
InitializeComponent();
}
private void Add_Click(object sender, RoutedEventArgs e)
{
SubWindow subWindow = new SubWindow();
RefreshListEvent += new RefreshList(RefreshListBox);
subWindow.UpdateActor = RefreshListEvent;
subWindow.Show();
}
private void RefreshListBox(DutyType dutyType)
{
//내근은 SelectedIndex를 0, 외근은 SelectedIndex를 1로 설정하여
//상단 ListBox의 선택값을 변경시킨다.
//상단 ListBox의 값이 바뀜에 따라 OnSelected 이벤트 핸들러가 호출되어
//자동으로 아래쪽 ListBox의 값은 변경된다.
myListBox1.SelectedItem = null;
myListBox1.SelectedIndex = (dutyType == DutyType.Inner) ? 0 : 1;
}
private void myListBox1_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
ListBox lb = sender as ListBox;
ListBoxItem item = lb.SelectedItem as ListBoxItem;
if(lb.SelectedItem != null)
{
string dutyType = item.Content.ToString();
this.DataContext = from duty in duties
where duty.DutyType.ToString() == dutyType
select duty;
}
}
private void myListBox2_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
var duty = (Duty)myListBox2.SelectedItem;
// string value = duty == null ? "No selection" : duty.ToString();
MessageBox.Show($"{duty.DutyName} :: {duty.DutyType}", "선택한 직무");
}
}
}
SubWindow.xaml
<Window x:Class="WPF07_Test.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:WPF07_Test"
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"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock FontFamily="20"
Grid.ColumnSpan="3"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="직무 등록"/>
<TextBlock Grid.Row="1" Margin="10"
VerticalAlignment="Center"
Text="직무명"/>
<TextBox x:Name="txtDutyName"
Grid.Row="1" Margin="10"
Grid.Column="1"
Grid.ColumnSpan="2"/>
<TextBlock Grid.Row="2" Margin="10"
Text="직무타입"/>
<RadioButton x:Name="rdoInner"
Grid.Row="2" Grid.Column="1"
Content="내근"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<RadioButton x:Name="rdoOutside"
Grid.Row="2" Grid.Column="2"
Content="외근"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<Button x:Name="btnSave"
Content="저장"
Grid.Column="1"
Grid.Row="3"
Width="100"
HorizontalAlignment="Center"
VerticalAlignment="Center" Height="22"
Click="btnSave_Click"/>
</Grid>
</Window>
SubWindow.xaml.cs
using System;
using System.Windows;
namespace WPF07_Test
{
/// <summary>
/// SubWindow.xaml에 대한 상호 작용 논리
/// </summary>
public partial class SubWindow : Window
{
//메인 윈도우의 하단 ListBox를 Refresh 하기 위한 델리게이트
//메인 윈도우에서 직무추가 버튼을 클릭할 때 이벤트를 할당해준다.
public Delegate UpdateActor;
public SubWindow()
{
InitializeComponent();
}
private void btnSave_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);
}
}
}
실행결과
728x90
'C# > WPF' 카테고리의 다른 글
9장. WPF 이벤트 라우팅(RoutedEvent), 버블링/ 터널링/다이렉트 이벤트 (0) | 2021.05.08 |
---|---|
8장. WPF 의존프로퍼티(DependencyProperty) 란? (0) | 2021.05.08 |
6장. WPF Data Trigger 란? (0) | 2021.05.08 |
5장. WPF 트리거란? (0) | 2021.05.06 |
4장. WPF 멀티쓰레드 프로그래밍 (0) | 2021.05.06 |
이 글을 공유하기