-
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
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번째는 선택입니다.
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
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
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 댓글