MVC를 기반으로 바인딩을 구성합니다.
1.Model클래스
- DataGrid용 모델클래스(CountryInformation)와 ComboBox(CommonType)용 Model클래스를 생성
- 생성한 클래스를 이용한 실제 바인딩이 이용할 메서드(GetCountryNameList, GetCountryInformationList)를 생성
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Data;
namespace Wpf_DataGrid_Sample.Model
{
class DropDownListModel
{
/// <summary>
/// 국가명리스트 Model
/// </summary>
/// <returns></returns>
public ObservableCollection<CommonType> GetCountryNameList()
{
ObservableCollection<CommonType> countryNames = new ObservableCollection<CommonType>();
countryNames.Add(new CommonType { Name = "한국", Value = "KR" });
countryNames.Add(new CommonType { Name = "미국", Value = "US" });
countryNames.Add(new CommonType { Name = "영국", Value = "GB" });
countryNames.Add(new CommonType { Name = "일본", Value = "JP" });
countryNames.Add(new CommonType { Name = "중국", Value = "CN" });
return countryNames;
}
/// <summary>
/// 국가정보리스트 Model
/// </summary>
/// <returns></returns>
public ObservableCollection<CountryInformation> GetCountryInformationList()
{
ObservableCollection<CountryInformation> countryNames = new ObservableCollection<CountryInformation>();
countryNames.Add(new CountryInformation { RowIndex = 1, CountryCode = "KR" });
countryNames.Add(new CountryInformation { RowIndex = 2, CountryCode = "US" });
countryNames.Add(new CountryInformation { RowIndex = 3, CountryCode = "GB" });
countryNames.Add(new CountryInformation { RowIndex = 4, CountryCode = "JP" });
countryNames.Add(new CountryInformation { RowIndex = 5, CountryCode = "CN" });
return countryNames;
}
}
/// <summary>
/// DataGrid용 모델클래스
/// </summary>
public class CountryInformation
{
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Property변경을 View에 전달
/// </summary>
/// <param name="propertyName"></param>
private void RaisePropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
private void SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
field = value;
var h = this.PropertyChanged;
if (h != null) { h(this, new PropertyChangedEventArgs(propertyName)); }
}
private int rowinde;
/// <summary>
/// 행번호
/// </summary>
public int RowIndex
{
get { return this.rowinde; }
set { this.SetProperty(ref this.rowinde, value); }
}
private string countrycode;
/// <summary>
/// 국가코드
/// </summary>
public string CountryCode
{
get { return this.countrycode; }
set { this.SetProperty(ref this.countrycode, value); }
}
}
/// <summary>
/// DropDownList의 데이터생성을 위한 CommonType 모델클래스
/// </summary>
public class CommonType : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Property변경을 View에 전달
/// </summary>
/// <param name="propertyName"></param>
private void RaisePropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
private void SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
field = value;
var h = this.PropertyChanged;
if (h != null) { h(this, new PropertyChangedEventArgs(propertyName)); }
}
private string value;
/// <summary>
/// 콤보막스 Value값(Value용)
/// </summary>
public string Value
{
get { return this.value; }
set { this.SetProperty(ref this.value, value); }
}
private string name;
/// <summary>
/// 콤보막스 Name값(Display용)
/// </summary>
public string Name
{
get { return this.name; }
set { this.SetProperty(ref this.name, value); }
}
}
}
2.Controller클래스
- DataGrid와ComboBox에 바인딩할 ViewItem생성
- ViewItem클래스의 Model(CountryNameList, CountryInformationList)에 Model클래스의 메서드(GetCountryNameList, GetCountryInformationList)를 불러올 메서드 생성(GetContryNameList, GetCountryInformationList)
- 중요포인트는 ViewItem클래스의 Model(CountryNameList, CountryInformationList)의 RaisePropertyChanged의 Property명과 실제 DataGrid와 ComboBox에 사용될 바인딩명이 동일해야 정상적으로 동작한다는 것입니다.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using Wpf_DataGrid_Sample.Model;
namespace Wpf_DataGrid_Sample.Controller
{
class DropDownListContoller
{
//Model 클래스 선언
DropDownListModel DropDownListModel = new DropDownListModel();
/// <summary>
/// DropDownlist 바인딩용 메서드
/// </summary>
/// <param name="dataContent"></param>
public void GetContryNameList(Object dataContext)
{
DropDownListViewItem viewItem = (DropDownListViewItem)dataContext;
viewItem.CountryNameList = DropDownListModel.GetCountryNameList();
return;
}
/// <summary>
/// DataGrid 바인딩용 메서드
/// </summary>
/// <param name="dataContent"></param>
public void GetContryInformationList(Object dataContext)
{
DropDownListViewItem viewItem = (DropDownListViewItem)dataContext;
viewItem.CountryInformationList = DropDownListModel.GetCountryInformationList();
return;
}
}
/// <summary>
/// DropDownList화면에 사용할ViewItem 클래스 선언
/// </summary>
class DropDownListViewItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Property변경을 View에 전달
/// </summary>
/// <param name="propertyName"></param>
private void RaisePropertyChanged(string propertyName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
/// <summary>
/// 국가명리스트 Model전달 메서드
/// </summary>
private ObservableCollection<CommonType> countryNameList;
public ObservableCollection<CommonType> CountryNameList
{
get { return countryNameList; }
set
{
countryNameList = value;
//ComboBox바인딩시 사용할 Name
RaisePropertyChanged("CountryNameList");
}
}
/// <summary>
/// 국가정보리스트 Model전달 메서드
/// </summary>
private ObservableCollection<CountryInformation> countryInformationList;
public ObservableCollection<CountryInformation> CountryInformationList
{
get { return countryInformationList; }
set
{
countryInformationList = value;
//DataGrid바인딩시 사용할 Name
RaisePropertyChanged("CountryInformationList");
}
}
}
}
3.View클래스
- 바인딩에 필요한 Controller를 선언합니다.
- DataContext는 Controller에 선언된ViewItem으로 초기화를 합니다.
- Contoller의 메소드와 DataContext를 매칭해서 바인딩 처리를 불러옵니다.
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;
using Wpf_DataGrid_Sample.Controller;
namespace Wpf_DataGrid_Sample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
//Controller선언
DropDownListContoller DropDownListContoller = new DropDownListContoller();
public MainWindow()
{
InitializeComponent();
this.DataContext = new DropDownListViewItem();
ViewInit();
}
/// <summary>
/// 화면초기화
/// </summary>
public void ViewInit()
{
//화면타이틀 설정
this.Title = "국가리스트";
//DataGrid내부에 있는 ComboBox에 국가리스트 바인딩
DropDownListContoller.GetContryNameList(this.DataContext);
//DataGrid데이터 바인딩
DropDownListContoller.GetContryInformationList(this.DataContext);
}
}
}
4.디자인소스
- 중요포인트는 Controller에 선언된 Model의 Property명과 동일해야 정상적으로 바인딩이 동작한다는 것입니다.
<Window x:Class="Wpf_DataGrid_Sample.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:Wpf_DataGrid_Sample"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="300">
<Grid>
<Grid.Resources>
<Style TargetType="DataGridCell">
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<!--DataContext에 매칭된 ViewItem에 선언된 모델의 Property명-->
<DataGrid x:Name="dgDropDownBinding" ItemsSource="{Binding CountryInformationList}" Height="Auto" VerticalAlignment="Top" Width="auto" AutoGenerateColumns="False" CanUserAddRows="False" SelectionMode="Single">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<Label Name="lbRowCount" Content="Row Number" VerticalAlignment="Center" HorizontalAlignment="Left"></Label>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock x:Name="nbRowCount" Text="{Binding RowIndex}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<Label Name="lbCountryName" Content="CountryName"></Label>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate> <!--DataContext에 매칭된 ViewItem에 선언된 모델의 Property명-->
<ComboBox Name="cbCountryName" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CountryNameList, Mode=OneWay}"
IsSynchronizedWithCurrentItem="False"
DisplayMemberPath="Name"
SelectedValuePath="Value"
SelectedValue="{Binding CountryCode}" Cursor="Hand" Height="25"></ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
5. 샘플화면
6. 참고사항
- 샘플소스를 참조해서 더좋은 코드를 만들어보세요.
'WPF' 카테고리의 다른 글
TextBlock의 Text의 Inlines 추가 Text의 색상지정 (0) | 2022.02.24 |
---|---|
DataGrid의 DataGridTemplateColumn안에서 Control (TextBlock)찾기 (0) | 2022.02.24 |
ListBox의 CheckBox가져오기 (0) | 2021.08.20 |
WPF 천단위 숫자입력 TextBox UserControl작성 (0) | 2021.02.27 |
WPF 년월선택 UserControl작성 (0) | 2021.02.27 |
댓글