// MainViewModel 클래스는 MVVM 패턴에서 View와 데이터를 연결하는 역할을 합니다.
// CommunityToolkit의 ObservableObject를 상속하여 속성 변경 알림(INotifyPropertyChanged)을 자동 구현합니다.
public partial class MainViewModel : ObservableObject
{
// 이름 입력을 저장하는 속성입니다.
// [ObservableProperty]를 사용하면 name 필드에 대해 Name 속성이 자동 생성되며,
// UI에서 바인딩 시 TextBox 등의 입력 변경이 자동 반영되고 변경 통지가 발생합니다.
[ObservableProperty]
private string? name;
// 인사 메시지를 저장하는 속성입니다.
// GreetingMessage 속성은 TextBlock에 바인딩되어 메시지를 화면에 출력합니다.
[ObservableProperty]
private string? greetingMessage;
// 체크박스와 바인딩되어 정중한 인사를 할지 여부를 제어하는 속성입니다.
[ObservableProperty]
private bool isPolite;
// 라디오 버튼과 바인딩되는 성별 선택 속성입니다.
[ObservableProperty]
private string? selectedGender;
// 버튼 클릭 시 실행되는 명령 메서드입니다.
// [RelayCommand] 특성을 붙이면 자동으로 SayHelloCommand 속성이 생성되어 XAML에서 바인딩 가능해집니다.
// 또한 CanExecute 조건으로 CanSayHello 메서드를 연결하여, 이름이 입력되지 않으면 버튼이 비활성화됩니다.
[RelayCommand(CanExecute = nameof(CanSayHello))]
private void SayHello()
{
// 체크박스 값에 따라 인사말을 다르게 설정
string greeting = isPolite ? "안녕하세요" : "하이";
// 선택된 성별에 따라 호칭을 다르게 설정
string? title = selectedGender switch
{
"남성" => "형님",
"여성" => "누님",
_ => "친구"
};
// 최종 인사 메시지를 구성하여 GreetingMessage 속성에 저장
GreetingMessage = $"{greeting}, {Name} {title}!";
}
// SayHelloCommand의 실행 가능 여부를 판단하는 메서드입니다.
// 이름이 입력되어 있어야 true 반환 → 버튼 활성화됨
private bool CanSayHello()
{
return !string.IsNullOrWhiteSpace(Name);
}
// 이름이 변경될 때마다 SayHelloCommand의 CanExecute 상태를 업데이트하여
// 버튼 활성화 여부를 즉시 반영합니다.
partial void OnNameChanged(string? value)
{
SayHelloCommand.NotifyCanExecuteChanged();
}
// 메시지를 초기화하는 명령입니다.
// 버튼과 ClearCommand로 바인딩되어 클릭 시 모든 속성을 기본값으로 되돌립니다.
[RelayCommand]
private void Clear()
{
GreetingMessage = string.Empty;
Name = string.Empty;
SelectedGender = null;
IsPolite = false;
}
}
🔍2.3 XAML 화면 구성
<!-- MainViewModel을 현재 View의 데이터 컨텍스트로 설정합니다.
이를 통해 XAML 내에서 ViewModel의 속성과 명령에 직접 접근할 수 있습니다. -->
<Window.DataContext>
<vm:MainViewModel />
</Window.DataContext>
<StackPanel Margin="20" VerticalAlignment="Center">
<!-- 사용자로부터 이름을 입력받는 TextBox입니다.
Name 속성과 양방향 바인딩되며, 텍스트가 입력될 때마다 ViewModel의 속성이 자동 갱신됩니다. -->
<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"
/>
<!-- 성별 선택을 위한 라디오 버튼 그룹입니다.
EqualsConverter를 사용해 SelectedGender 속성과 양방향으로 바인딩되며,
남성/여성 중 하나를 선택할 수 있습니다. -->
<TextBlock Text="성별 선택:" />
<StackPanel Orientation="Horizontal">
<RadioButton Content="남성" GroupName="Gender"
IsChecked="{Binding SelectedGender, Converter={StaticResource EqualsConverter}, ConverterParameter=남성}" />
<RadioButton Content="여성" GroupName="Gender"
IsChecked="{Binding SelectedGender, Converter={StaticResource EqualsConverter}, ConverterParameter=여성}" />
</StackPanel>
<!-- 체크박스를 통해 정중한 인사를 사용할지 여부를 설정합니다.
IsPolite 속성과 바인딩되어 값이 ViewModel에 실시간 반영됩니다. -->
<CheckBox Content="정중한 인사 사용" IsChecked="{Binding IsPolite}"/>
<!-- SayHelloCommand에 바인딩된 버튼입니다.
이름이 입력되어 있을 경우에만 활성화되며, 클릭 시 인사 메시지를 생성합니다. -->
<Button Content="인사하기" Command="{Binding SayHelloCommand}"/>
<!-- ClearCommand에 바인딩된 버튼입니다.
클릭 시 모든 입력 값과 인사 메시지를 초기화합니다. -->
<Button Content="메시지 초기화" Command="{Binding ClearCommand}" />
<!-- ViewModel의 GreetingMessage 속성과 바인딩되어 생성된 인사 메시지를 표시합니다. -->
<TextBlock Text="{Binding GreetingMessage}" FontSize="16" FontWeight="Bold"
TextWrapping="Wrap"/>
</StackPanel>
🔍2.4추가 클래스: EqualsConverter.cs (라디오버튼 바인딩을 위해 필요)
// EqualsConverter는 주로 WPF의 라디오 버튼과 ViewModel 속성 간 바인딩에 사용됩니다.
// MVVM 패턴에서 문자열 값을 비교하거나 특정 값과 매칭될 때 체크 상태를 결정할 수 있도록 도와주는 변환기입니다.
public class EqualsConverter : IValueConverter
{
// Convert 메서드는 ViewModel의 속성 값(value)과 ConverterParameter를 비교하여,
// 두 값이 같으면 true, 다르면 false를 반환합니다.
// 이 값은 IsChecked 속성에 바인딩되어 라디오 버튼이 선택 상태인지 여부를 결정합니다.
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value?.ToString() == parameter?.ToString();
}
// ConvertBack 메서드는 라디오 버튼이 선택되었는지를 나타내는 bool 값을 받아서,
// true일 경우 해당 ConverterParameter 값을 ViewModel에 전달하고,
// false일 경우 바인딩을 하지 않습니다(Binding.DoNothing).
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (bool)value ? parameter?.ToString() : Binding.DoNothing;
}
}
🔍2.5 XAML 화면 구성App.xaml 어플리케이션 전역 리소스 등록
<Application.Resources>
<!--
EqualsConverter는 라디오 버튼의 선택 상태(IsChecked)와 ViewModel의 문자열 속성 간의 바인딩을 지원합니다.
예: SelectedGender 속성이 "남성"일 때만 특정 라디오 버튼이 선택되도록 제어할 수 있습니다.
이 리소스 등록은 View (XAML) 전역에서 EqualsConverter를 재사용할 수 있도록 메모리에 상주시키며,
x:Key="EqualsConverter"를 통해 바인딩 시 참조할 수 있습니다.
사용 예:
<RadioButton Content="남성"
IsChecked="{Binding SelectedGender, Converter={StaticResource EqualsConverter}, ConverterParameter=남성}" />
위 바인딩은 SelectedGender == "남성" 일 때 해당 라디오 버튼이 선택됨(IsChecked = true).
반대로 해당 버튼을 선택하면 SelectedGender 속성 값이 "남성"으로 설정됩니다.
-->
<local:EqualsConverter x:Key="EqualsConverter"/>
</Application.Resources>