[WPF] MVVM 패턴 적용하여 동적으로 Button 컨트롤 생성하는 방법

안녕하세요.

 

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

 

MVVM 패턴 적용만 하지 않으면..그냥 View 비하인드 코드에서..Button 객체 생성하면 되는데요..

 

MVVM 패턴으로 컨트롤 동적 생성하려니까..많이 어렵더라고요ㅠㅠ

 

저도 구글링 해서 얻은 정보를 토대로 만든거니까 참고해 주세요!ㅎㅎ

 

그럼 바로 예제 코드를 통해 어떻게 동적으로 Button 컨트롤을 생성하는지 보여드리겠습니다.

 

 

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
<Window x:Class="WpfApp1.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:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
 
    <StackPanel>
        <Button Content="Add TextBox" Command="{Binding TestCommand}"/>
        <ItemsControl x:Name="MyItems" ItemsSource="{Binding ButtonCollection}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding Path=., Mode=TwoWay, 
                        UpdateSourceTrigger=PropertyChanged}"
                            FontWeight="Bold"
                            FontSize="18"
                            Command="{Binding ElementName=MyItems,
                        Path=DataContext.SubButtonCommand}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
</Window>
 
cs

 

MainWindowViewModel.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
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
 
namespace WpfApp1
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<string> ButtonCollection { get; set; }
        public ICommand TestCommand { get; private set; }
        public ICommand SubButtonCommand { get; private set; }
 
        public MainWindowViewModel()
        {
            ButtonCollection = new ObservableCollection<string>();
            TestCommand = new RelayCommand<object>(CommandMethod);
            SubButtonCommand = new RelayCommand<object>(SubCommandMethod);
        }
 
        private void CommandMethod(object parameter)
        {
            for (int idx = 0; idx < 4; idx++)
            {
                ButtonCollection.Add($"Button {idx}");
            }
        }
 
        private void SubCommandMethod(object parameter)
        {
            ButtonCollection.Add($"Button1");
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
cs

 

RelayCommand.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
using System;
using System.Windows.Input;
 
namespace WpfApp1
{
    public class RelayCommand<T> : ICommand
    {
        readonly Action<T> _execute = null;
        readonly Predicate<T> _canExecute = null;
 
        public RelayCommand(Action<T> execute, Predicate<T> canExecute = null)
        {
            _execute = execute ?? throw new ArgumentNullException(nameof(execute));
            _canExecute = canExecute;
        }
 
        public bool CanExecute(object parameter)
        {
            return _canExecute?.Invoke((T)parameter) ?? true;
        }
 
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
 
        public void Execute(object parameter)
        {
            _execute((T)parameter);
        }
    }
}
 
cs

 

실행 결과

위와 같이 Add Button 이 하나 있고, ItemSource 속성에 ObservableCollection 객체를 바인딩 시켜서 버튼을 클릭하니까 새로운 Button들이 생성 되는 것을 확인하실 수 있습니다.

위와 비슷한 기능들이 필요할 때 유용하게 사용할 소스코드인 것 같아요!

 

감사합니다.^^

728x90

이 글을 공유하기

댓글

Designed by JB FACTORY