[WPF] WPF MVVM 패턴 적용하여 DataGrid 컨트롤 동적 컬럼 데이터 바인딩하기

안녕하세요.

 

오늘은 WPF에서 MVVM 패턴을 이용하여 DataGrid 컨트롤에서 동적으로 컬럼을 생성해서 데이터 바인딩 하는 방법에 대해서 알려 드리려고 합니다.

 

제가 프로젝트를 하면서 파일마다 Column이 달라서 매번 다른 컬럼의 정보를 알아와 DataGrid 에 보여줘야 했던 경우가 있었는데요.

 

이때 유용하게 사용했던 방법으로 아래 소스코드를 응용하시면 되겠습니다.

 

저는 DataTable을 이용하여 데이터를 담아두고 있었고 DataTableDataGrid에 바인딩하였습니다.

 

예제 코드는 아래와 같습니다.

 

 

MainWindow.xaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<Window x:Class="DataGridTest.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:DataGridTest"
        xmlns:vm ="clr-namespace:DataGridTest.ViewModel"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="400">
 
 
    <Window.Resources>
        <Style x:Key="dataGrid" TargetType="DataGrid">
            <Setter Property="RowBackground" Value="White" />
            <Setter Property="Foreground" Value="Black" />
            <Setter Property="HorizontalGridLinesBrush" Value="#FF2F2F2F" />
            <Setter Property="VerticalGridLinesBrush" Value="#FF2F2F2F" />
            <Setter Property="RowHeaderWidth" Value="0"/>
            <Setter Property="BorderBrush" Value="Black"/>
            <Setter Property="MaxHeight" Value="400"/>
            <Setter Property="Background" Value="White"/>
            <Setter Property="CanUserAddRows" Value="false"/>
            <Setter Property="CanUserDeleteRows" Value="false"/>
            <Setter Property="IsReadOnly" Value="true"/>
            <Setter Property="AutoGenerateColumns" Value="true"/>
        </Style>
    </Window.Resources>
 
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        
        <DataGrid Grid.ColumnSpan="3" Margin="5" Grid.Row="0"
                  ColumnWidth="*"
                  ItemsSource="{Binding ResultDataTable}"
                  Style="{StaticResource dataGrid}">
 
        </DataGrid>
 
        <Button VerticalAlignment="Center" HorizontalAlignment="Center"
                Grid.Row="1" Content="Update"
                Command="{Binding UpdateCommand}"/>
 
    </Grid>
 
</Window>
 
cs

 

DelegateCommand.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using System;
using System.Windows.Input;
 
namespace DataGridTest.ViewModel
{
    class DelegateCommand : ICommand
    {
        private readonly Func<bool> canExecute;
        private readonly Action execute;
 
        public DelegateCommand(Action exectue) : this(exectue, null)
        {
 
        }
 
        public DelegateCommand(Action execute, Func<bool> canExecute)
        {
            this.execute = execute;
            this.canExecute = canExecute;
        }
 
        /// <summary>
        /// can executes event handler
        /// </summary>
        public event EventHandler CanExecuteChanged;
 
        /// <summary>
        /// implement of icommand can execute method
        /// </summary>
        /// <param name="o">parameter by default of icomand interface</param>
        /// <returns>can execute or not</returns>
        public bool CanExecute(object o)
        {
            if (this.canExecute == null)
            {
                return true;
            }
            return this.canExecute();
        }
 
        /// <summary>
        /// implement of icommand interface execute method
        /// </summary>
        /// <param name="o">parameter by default of icomand interface</param>
        public void Execute(object o)
        {
            this.execute();
        }
 
        /// <summary>
        /// raise ca excute changed when property changed
        /// </summary>
        public void RaiseCanExecuteChanged()
        {
            if (this.CanExecuteChanged != null)
            {
                this.CanExecuteChanged(this, EventArgs.Empty);
            }
        }
    }
}
 
 
 
cs

 

MainViewModel.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using System.Data;
using System.Windows.Input;
 
namespace DataGridTest.ViewModel
{
    public class MainWindowViewModel : BaseVM
    {
        public MainWindowViewModel(MainWindow ownerWindow)
        {
            _resultDT = GetSampleData();
        }
 
        DataTable _resultDT = null;
        public DataTable ResultDataTable
        {
            get { return _resultDT; }
            set
            {
                _resultDT = value;
                OnPropertyChanged("ResultDataTable");
            }
        }
 
        private ICommand updateCommand;
        public ICommand UpdateCommand
        {
            get
            {
                return (this.updateCommand) ?? 
(this.updateCommand = new DelegateCommand(UpdateDataGrid));
            }
        }
 
        public void UpdateDataGrid()
        {
            _resultDT.Columns.Clear();
            _resultDT.Rows.Clear();
 
            DataTable dt = new DataTable();
            dt.Columns.Add("이름"typeof(string));
            dt.Columns.Add("나이"typeof(int));
 
            dt.Rows.Add("남길동1"12);
            dt.Rows.Add("남길동2"14);
            dt.Rows.Add("남길동3"15);
            dt.Rows.Add("남길동4"16);
 
            ResultDataTable = dt;
        }
 
        public DataTable GetSampleData()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Name"typeof(string));
            dt.Columns.Add("Age"typeof(int));
            
            dt.Rows.Add("홍길동1"12);
            dt.Rows.Add("홍길동2"14);
            dt.Rows.Add("홍길동3"15);
            dt.Rows.Add("홍길동4"16);
 
            return dt;
        }
    }
}
cs

 

BaseVM.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.ComponentModel;
 
namespace DataGridTest.ViewModel
{
    public class BaseVM : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
 
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
 
cs

 

실행 결과

위와 같이 처음 프로그램이 시작하면 첫 DataTable의 값이 나오게 되고, Update 버튼을 클릭하게 되면 새로운 컬럼과 정보로 다시 Update 되어 데이터가 보여지는 것을 확인하실 수 있습니다.

 

감사합니다.^^

728x90

이 글을 공유하기

댓글

Designed by JB FACTORY