ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [WPF]MVVM
    C#/WPF 2022. 7. 11. 11:52

     

    https://blog.arong.info/wpf/2022/01/21/WPF-WPF-MVVM-%ED%8C%A8%ED%84%B4%EC%97%90-%EB%8C%80%ED%95%B4.html

     

    (WPF) WPF MVVM 패턴에 대해 - Arooong Blog

    복잡한 프로그램일 수록 기본적인 설계단계에 있어 항상 다음과 같은 사항을 고려하지 않을 수 없습니다. 공통적 부분의 재사용성, 의존성 등 그리고 이런 고민은 어떻게 하면 효율적으로 사용

    blog.arong.info

     

     

    DataContext

    <Window x:Class="MVVM_Example.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:MVVM_Example"
            xmlns:views="clr-namespace:MVVM_Example.Views"	//Views폴더 views이름으로 참조
            xmlns:viewModels="clr-namespace:MVVM_Example.ViewModels" //ViewModels폴더 viewModels이름으로 참조
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <!--DataContext Code IntelliSense-->
        <Window.DataContext>
            <viewModels:FirstViewModel/>	// 코드상에서 new FirstViewModel과 비슷
        </Window.DataContext>
        
        <Grid Margin="20 10">
            <views:FirstView />	//뷰
        </Grid>
    </Window>

    DataContext 뷰모델 연결

    <Window.DataContext>
            <viewModels:FirstViewModel/>
        </Window.DataContext>

     

    위 코드 DataContext Code IntelliSense 가능하게 함. ( xaml상에서 FirstViewModel의 프로퍼티 Binding 시 코드인텔리젠스로 오류검출 가능.)

     

    View 디스플레이

    <Grid Margin="20 10">
            <views:FirstView />
        </Grid>


    ICommand

    CommandBase

    namespace MVVM_Example.Commands
    {
        public abstract class CommandBase : ICommand
        {
            public event EventHandler? CanExecuteChanged;
    
            public virtual bool CanExecute(object? parameter)
            {
                return true;
            }
             //abstract메소드 사용시 class도 abstract선언 되어있어야 함.
             //public abstract class CommandBase : ICommand
            public abstract void Execute(object? parameter);
    
            protected void OnCanExecuteChanged()
            {
                CanExecuteChanged?.Invoke(this, new EventArgs());
            }
        }
    }

     

    메소드 전달 Command

    RelayCommand

    public class RelayCommand<T> : ICommand
    {
        readonly Action<T> _execute = null;
        readonly Predicate<T> _canExecute = null;
    
        public RelayCommand(Action<T> execute)
            : this(execute, null)
        {
        }
    
        public RelayCommand(Action<T> execute, Predicate<T> canExecute)
        {
            _execute = execute ?? throw new ArgumentNullException("execute");
            _canExecute = canExecute;
        }
        
        public event EventHandler CanExecuteChanged;
        /*
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
        */
    
        public bool CanExecute(object parameter)
        {
            return _canExecute == null || _canExecute((T)parameter);
        }
        
        public void Execute(object parameter)
        {
            _execute((T)parameter);
        }
    }

     

    	public ICommand DisplayInformationCommand { get; set; }
    
            public FirstViewModel()
            {
                DisplayInformationCommand = new RelayCommand<object>(OnUserInformationChanged);
            }
    
            public void OnUserInformationChanged(object sender)
            {
                OnPropertyChanged(nameof(UserInformation));
            }

     

    namespace Canvas1
    {
        public class RelayCommand<T> : ICommand
        {
            private readonly Predicate<T> _canExecute;
            private readonly Action<T> _execute;
    
            public RelayCommand(Action<T> execute)
               : this(execute, null)
            {
                _execute = execute;
            }
    
            public RelayCommand(Action<T> execute, Predicate<T> canExecute)
            {
                if (execute == null)
                    throw new ArgumentNullException(nameof(execute));
                _execute = execute;
                _canExecute = canExecute;
            }
    
            #region ICommand Members
    
            public bool CanExecute(object parameter)
            {
                return (_canExecute == null) || _canExecute((T)parameter);
            }
    
            public void Execute(object parameter)
            {
                _execute((T)parameter);
            }
    
            public event EventHandler CanExecuteChanged
            {
                add { CommandManager.RequerySuggested += value; }
                remove { CommandManager.RequerySuggested -= value; }
            }
    
            #endregion
        }
    
        public class RelayCommand : ICommand
        {
            private readonly Predicate<object> _canExecute;
            private readonly Action<object> _execute;
    
            public RelayCommand(Action<object> execute)
               : this(execute, null)
            {
                _execute = execute;
            }
    
            public RelayCommand(Action<object> execute, Predicate<object> canExecute)
            {
                if (execute == null)
                    throw new ArgumentNullException("execute");
                _execute = execute;
                _canExecute = canExecute;
            }
    
            #region ICommand Members
    
            public bool CanExecute(object parameter)
            {
                return (_canExecute == null) || _canExecute(parameter);
            }
    
            public void Execute(object parameter)
            {
                _execute(parameter);
            }
    
            // Ensures WPF commanding infrastructure asks all RelayCommand objects whether their
            // associated views should be enabled whenever a command is invoked 
            public event EventHandler CanExecuteChanged
            {
                add
                {
                    CommandManager.RequerySuggested += value;
                }
                remove
                {
                    CommandManager.RequerySuggested -= value;
                }
            }
    
            #endregion
    
    }

     

     


    new ViewModel();

    public partial class App : Application
        {
            protected override void OnStartup(StartupEventArgs e)
            {
                MainWindow = new MainWindow()
                {
                    DataContext = new MainViewModel() // <ContentControl Content="{Binding CurrentViewModel}"/> 성립
                    //DataContext = new FirstViewModel()
                };
                MainWindow.Show();
    
                base.OnStartup(e);
            }
        }
    namespace MVVM_Example.ViewModels
    {
        public class MainViewModel : ViewModelBase
        {
            public ViewModelBase CurrentViewModel { get; }
    
            public MainViewModel()
            {
                CurrentViewModel = new FirstViewModel();
                /*
                <DataTemplate DataType="{x:Type viewModels:FirstViewModel}">
                <views:FirstView/>
             </DataTemplate>
             성립
             */
            }
        }
    }
    <Window x:Class="MVVM_Example.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:MVVM_Example"
            xmlns:views="clr-namespace:MVVM_Example.Views"
            xmlns:viewModels="clr-namespace:MVVM_Example.ViewModels"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        
        <Window.Resources>
            <DataTemplate DataType="{x:Type viewModels:FirstViewModel}">
                <views:FirstView/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type viewModels:SecondViewModel}">
                <views:SecondView/>
            </DataTemplate>
        </Window.Resources>
        
        <Grid Margin="20 10">
            <ContentControl Content="{Binding CurrentViewModel}"/>
        </Grid>
    </Window>

                    DataContext = new MainViewModel() 로 인하여 

            <ContentControl Content="{Binding CurrentViewModel}"/> 바인딩 성립되고 

                CurrentViewModel = new FirstViewModel(); 로 

     

     <Window.Resources>
            <DataTemplate DataType="{x:Type viewModels:FirstViewModel}">
                <views:FirstView/> //이 부분 성립
            </DataTemplate>
            <DataTemplate DataType="{x:Type viewModels:SecondViewModel}">
                <views:SecondView/>
            </DataTemplate>
        </Window.Resources>


     

     

    참조 사이트

    https://kaki104.tistory.com/531

     

    MVVM Pattern을 사용하는 개발자를 위한 안내 (업데이트 : 2022/03/21)

    2022.07.05 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part6 Command 2022.06.27 - [WPF .NET] - MVVM Pattern을 사용하는 개발자를 위한 안내 V1.0 part5 Converter 2022.06.15 - [WPF .N..

    kaki104.tistory.com

    https://blog.naver.com/vactorman/221013790924

     


    DependencyProperty 

    public string Name
            {
                get { return (string)GetValue(NameProperty); }
                set { SetValue(NameProperty, value); }
            }
    
            // Using a DependencyProperty as the backing store for Title.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty NameProperty =
                DependencyProperty.Register("Name", typeof(string), typeof(ClassName), new PropertyMetadata("", new PropertyChangedCallback(NameChanged)), , ValidateName);

    1번째 인자 Name=> 이름을 등록합니다.

    2번째 인자 typeof(string) => 사용할 타입을 입력합니다.

    3번째 인자 typeof(ClassName) => NameProperty를 소유한 클래스를 입력합니다.

    4번째 인자 new PropertyMetadata(" ", new PropertyChangedCallback(NameChanged)) => " "는 초기값, typeof(type)에 따라 초기화값 지정 ex) typof(int) 이면 0, typof(string)이면 "string"

    NameChanged는 값이 변경되면 호출될 함수를 입력합니다.

    5번째 인자 ValidateName=> 값이 변경될 때 값을 검사할 함수를 입력합니다.

     

    4번째, 5번째는 선택입니다.

     

    https://bbicw.tistory.com/6

     

    [WPF] 의존 프로퍼티!?

    안녕하세요. 간단하게 따라 할 수 있는 예제를 만드는 Teemol입니다! 오늘의 예제는 WPF Dependency Property의 간단한 사용법만 알려드리려고 합니다. 여기서 Dependency Property(의존 프로퍼티)란, 의존 속

    bbicw.tistory.com


    TextBox에서 Enter시 Command 실행

     

    <!-- MainWindow.xaml -->
    <Window x:Class="WPF_TextBox_KeyBinding.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_TextBox_KeyBinding"
            mc:Ignorable="d"
            Title="MainWindow" Height="100" Width="300">
        <Grid>
            <TextBox Text="{Binding Id, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center" Width="200" FontSize="15">
                <TextBox.InputBindings>
                    <KeyBinding Command="{Binding LoginCommand}" Key="Enter"/>
                </TextBox.InputBindings>
            </TextBox>
        </Grid>
    </Window>

    https://chashtag.tistory.com/57

     

    [C# WPF] MVVM패턴 TextBox Enter눌렀을 때 Command (KeyBinding)

    안녕하세요. 오늘은 WPF MVVM패턴에서 TextBox에서 특정 버튼을 눌렀을 때 ViewModel의 함수로 연결하는 방법에 대해 알아보도록 하겠습니다. 우선 View입니다. 여기서 중요하게 보여야 할 부분은 두 가

    chashtag.tistory.com


     

    TextBox 숫자만 입력

    XAML:
    
    1
    <TextBox
                    Grid.Row="1"
                    Margin="0 5 0 0 "
                    PreviewTextInput="NumberValidationTextBox"
                    Text="{Binding UserID, UpdateSourceTrigger=PropertyChanged}"/>
    5
    private void NumberValidationTextBox(object sender, TextCompositionEventArgs e)
    {
        Regex regex = new Regex("[^0-9]+");
        e.Handled = regex.IsMatch(e.Text);
    }

     

    https://stackoverflow.com/questions/50606518/wpf-xaml-binding-to-textbox-previewtextinput-event

     

    WPF/XAML - Binding to TextBox PreviewTextInput Event

    I am trying to bind the Textbox 'PreviewTextInput' to method in the viewmodel. I am following the this article But my method is never called. Here is my code in XAML: <UserControl x:Class="

    stackoverflow.com

    https://stackoverflow.com/questions/25087120/what-is-a-command-method-in-the-context-of-the-mvvm-pattern-using-prism

     

    What is a command method in the context of the MVVM pattern using PRISM?

    Reading the following information, I am still stumped about what is meant by a Command method as opposed to a Command object. http://msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx#sec10...

    stackoverflow.com

    xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

    사용

     


     

    TextBox 유효성 검사

    XAML

    <UserControl x:Class="MVVM_Example.Views.SecondView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:MVVM_Example.Views"
                 xmlns:rules="clr-namespace:MVVM_Example.Rules"
                 mc:Ignorable="d" 
                 d:DesignHeight="450" d:DesignWidth="800">
    
    <Grid>
    
    
    <TextBox 
                    Grid.Row="1"
                    Margin="0 5 0 0 ">
                    <TextBox.Text>
                        <Binding Path="UserID"
                                 UpdateSourceTrigger="PropertyChanged">
                            <Binding.ValidationRules>
                                <rules:OnlyDigitsValidationRule/>
                            </Binding.ValidationRules>
                        </Binding>
                    </TextBox.Text>
                </TextBox>
                
    </Grid>

    OnlyDigitsValidationRule.cs

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    using System.Windows.Controls;
    
    namespace MVVM_Example.Rules
    {
        public class OnlyDigitsValidationRule : ValidationRule
        {
            public override ValidationResult Validate(object value, CultureInfo cultureInfo)
            {
                var validationResult = new ValidationResult(true, null);
    
                if (value != null)
                {
                    if (!string.IsNullOrEmpty(value.ToString()))
                    {
                        var regex = new Regex("[^0-9.-]+"); //regex that matches disallowed text
                        var parsingOk = !regex.IsMatch(value.ToString());
                        if (!parsingOk)
                        {
                            validationResult = new ValidationResult(false, "Illegal Characters, Please Enter Numeric Value");
                        }
                    }
                }
    
                return validationResult;
            }
    
        }
    }

    EventTrigger

    <TextBox Grid.Row="3" 
                         Text="{Binding PhoneNumber, UpdateSourceTrigger=PropertyChanged}" 
                         Padding="2">
                    <i:Interaction.Triggers>
                        <i:EventTrigger EventName="PreviewTextInput">
                            <i:CallMethodAction TargetObject="{Binding}" MethodName="NumberValidationTextBox"/>
                        </i:EventTrigger>
                    </i:Interaction.Triggers>
                </TextBox>

     

     

    728x90

    'C# > WPF' 카테고리의 다른 글

    [WPF]ListBox 내에서 Button Command Binding  (0) 2022.09.05
    [WPF] Image source (Binding)  (0) 2022.09.05
    [WPF] Data Binding  (0) 2022.07.06
    [WPF] DateTime  (0) 2022.06.30
    [WPF] MVVM pattern  (0) 2022.06.29

    댓글

Designed by Tistory.