독개

[WPF] 바인딩 ViewModel 전체 틀

by #독개#

결과

결과물 이미지
WpfApp2.zip
0.08MB

솔루션

솔루션이미지

View.xaml

<window.DataContext>를 xalml에 클래스 정의해주면 Window 생성자에서 InitializeComponent(); 할때

정의된 클래스를 생성하고 this.DataContext에 주소를 할당한다

아래 예제에선

ViewModelMain v = new ViewModelMain();

this.DataContext = v;

이를 xaml에 넣어줬다 보면된다

그리고 네임스페이스를  xmls:viewmodel에 새로이 정의해주었다

<Window
    x:Class="WpfApp2.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:local="clr-namespace:WpfApp2"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:viewmodel="clr-namespace:WpfApp2.ViewModel"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">

    <Window.DataContext>
        <viewmodel:ViewModelMain />
    </Window.DataContext>
    <StackPanel>
        <TextBlock
            Background="DarkGray"
            FontSize="15"
            Text="{Binding Tb1}" />
        <TextBlock
            Background="DarkBlue"
            FontSize="15"
            Foreground="White"
            Text="{Binding Tb2}" />
        <Button
            Height="50"
            Margin="50,0,50,0"
            Background="Pink"
            Command="{Binding RefreshTextBox}"
            Content="변경" />
    </StackPanel>
</Window>

View.xaml.cs

완전 깔끔하다

using System.Windows;

namespace WpfApp2
{
    public partial class View : Window
    {
        public View()
        {
            InitializeComponent();
        }
    }
}

ViewModelMain.cs

using System.Windows.Input;

namespace WpfApp2.ViewModel
{
    public class ViewModelMain : ViewModelBase
    {
        #region Field
        private string _tb1;
        private string _tb2;

        public string Tb1
        {
            get => _tb1;
            set
            {
                _tb1 = value;
                OnPropertyChanged(); //CallerMemberName에 의해 자동으로 인자에 string Tb1이 들어간다
            }
        }

        public string Tb2
        {
            get => _tb2;
            set
            {
                _tb2 = value;
                OnPropertyChanged();
            }
        }
        #endregion


        public ICommand RefreshTextBox { get; }

        public ViewModelMain()
        {
            RefreshTextBox = new ViewModelCommand(ExecuteRefreshTextBox);
        }

        public void ExecuteRefreshTextBox(object obj)
        {
            Tb1 = "안녕";
            Tb2 = "바꼇나";
        }
    }
}

ViewModelBase

더보기
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace WpfApp2.ViewModel
{
    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        //public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        //{
        //    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        //}
    }
}

ViewModelCommand

타강의에선 RelayCommand로 파일이름을 두는 경우도 많다

더보기
using System;
using System.Windows.Input;

namespace WpfApp2.ViewModel
{
    public class ViewModelCommand : ICommand
    {
        //Fileds
        private readonly Action<object> _executeAction;
        private readonly Predicate<object> _canExcuteAction;

        //constructors
        public ViewModelCommand(Action<object> executeAction)
        {
            _executeAction = executeAction;
            _canExcuteAction = null;
        }

        public ViewModelCommand(Action<object> executeAction, Predicate<object> canExcuteAction)
        {
            _executeAction = executeAction;
            _canExcuteAction = canExcuteAction;
        }

        //Events
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        //Methods
        public bool CanExecute(object parameter)
        {
            return _canExcuteAction == null ? true : _canExcuteAction(parameter);
        }

        public void Execute(object parameter)
        {
            _executeAction(parameter);
        }
    }
}

 

블로그의 정보

독한 개발자

#독개#

활동하기