예를 들어서 정보를 입력받는 WPF 창이 있습니다. 그 창은 특정 클래스에서만 사용되고 그 특정 클래스에 텍스트박스에 입력된 정보를 전달하는 속성이 있어야 합니다.
처음에는 MVVM 패턴을 무시하고 창 클래스에 때려박으려(?)했는데 private set으로 설정해 보니까 읽기 전용 속성이라면서 예외가 나는겁니다.
그래서 인텔리센스에서 해주는 대로 뷰모델 클래스를 만들었는데 이번에는 그 뷰모델에 접근하는 방법이 없는겁니다.
그래서 뷰모델을 필드로 만들고 그 필드를 DataContext로 설정해서 만들었는데 이렇게 해도 MVVM 원칙에 위배되지는 않는지 궁금합니다.
public sealed class WizardViewModel : INotifyPropertyChanged {
private string modTitle;
private string modAuthors;
private string modSpecialThanks;
private string modDescription;
public event PropertyChangedEventHandler PropertyChanged;
public string ModTitle {
get => modTitle;
set => setProperty(ref modTitle, value);
}
public string ModAuthors {
get => modAuthors;
set => setProperty(ref modAuthors, value);
}
public string ModSpecialThanks {
get => modSpecialThanks;
set => setProperty(ref modSpecialThanks, value);
}
public string ModDescription {
get => modDescription;
set => setProperty(ref modDescription, value);
}
private bool setProperty<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null) {
if (!Equals(field, newValue)) {
field = newValue;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
return true;
}
return false;
}
}
public sealed partial class WizardWindow {
private readonly WizardViewModel viewModel;
public WizardWindow() {
InitializeComponent();
viewModel = new();
DataContext = viewModel;
}
public string ModTitle => viewModel.ModTitle;
public string ModAuthors => viewModel.ModAuthors;
public string ModSpecialThanks => viewModel.ModSpecialThanks;
public string ModDescription => viewModel.ModDescription;
private void OKButton_Click(object sender, RoutedEventArgs e) => DialogResult = true;
private void CancelButton_Click(object sender, RoutedEventArgs e) => DialogResult = false;
}
<Window x:Class="Civ6ModBuddyAlt.Wizards.WizardWindow"
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:Civ6ModBuddyAlt.Wizards"
mc:Ignorable="d"
Width="650" Height="500" Title="General Mod Info" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<Grid>
<TextBlock Text="Mod Title: " HorizontalAlignment="Left" VerticalAlignment="Top" Margin="38,10,0,0" TextWrapping="NoWrap" />
<TextBox x:Name="TitleBox" Text="{Binding Path=ModTitle}" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,10,10,0" TextWrapping="NoWrap" Width="528" />
<TextBlock Text="Mod Authors: " HorizontalAlignment="Left" VerticalAlignment="Top" Margin="18,34,0,0" TextWrapping="NoWrap" />
<TextBox x:Name="AuthorsBox" Text="{Binding Path=ModAuthors}" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,33,10,0" TextWrapping="NoWrap" Width="528" />
<TextBlock Text="Special Thanks: " HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,57,0,0" TextWrapping="NoWrap" />
<TextBox x:Name="SpecialThanksBox" Text="{Binding Path=ModSpecialThanks}" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,56,10,0" TextWrapping="NoWrap" Width="528" />
<TextBlock Text="Description: " HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,78,0,0" TextWrapping="NoWrap" />
<TextBox x:Name="DescriptionBox" Text="{Binding Path=ModDescription}" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,99,0,0" TextWrapping="Wrap" Width="620" Height="325" VerticalScrollBarVisibility="Auto" />
<Button x:Name="OKButton" Content="_OK" Width="75" Height="25" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,90,10" Click="OKButton_Click" />
<Button x:Name="CancelButton" Content="_Cancel" Width="75" Height="25" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,10,10" Click="CancelButton_Click" />
</Grid>
</Window>