<Window x:Class="영어단어맞추기.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:영어단어맞추기"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Label Content="{Binding WrongStatus}"
FontWeight="Bold"
HorizontalAlignment="Center"
></Label>
<Label Content="{Binding SelKor}"
FontSize="30"
HorizontalAlignment="Center"
></Label>
<Label Content="{Binding SelEng}"
FontSize="40"
HorizontalAlignment="Center"
></Label>
<Label Content="{Binding Message}"
FontWeight="Bold"
Foreground="White"
Background="Red"
HorizontalContentAlignment="Center"
></Label>
<Button Content="다시하기"
HorizontalAlignment="Center"
Width="100" Margin="10"
Click="Button_Click">
</Button>
</StackPanel>
<UniformGrid Grid.Row="1">
<ItemsControl Name="ic">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="10"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button
Content="{Binding .}"
FontSize="30"
FontWeight="Bold"
Background="Salmon"
Foreground="White"
Margin="10"
Click="Button_Click_1"
/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</UniformGrid>
</Grid>
</Window>
namespace 영어단어맞추기
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if(handler != null) handler(this, new PropertyChangedEventArgs(name));
}
private string wrongStatus;
private string selEng;
private string selKor;
private string message;
private List<char> btns = new List<char>();
public string WrongStatus {
get => wrongStatus;
set
{
wrongStatus = value;
OnPropertyChanged("WrongStatus");
}
}
public string SelEng
{
get => selEng;
set
{
selEng = value;
OnPropertyChanged("SelEng");
}
}
public string SelKor
{
get => selKor;
set
{
selKor = value;
OnPropertyChanged("SelKor");
}
}
public string Message
{
get => message;
set
{
message = value;
OnPropertyChanged("Message");
}
}
List<char> SelWord = new List<char>();
List<string> words = new List<string>()
{
"boy,소년",
"school,학교",
"fish,물고기",
"car,자동차",
"book,책"
};
int wrong = 0;
int maxWrong = 3;
string compareWord = string.Empty;
public MainWindow()
{
InitializeComponent();
DataContext = this;
btns.AddRange("abcdefghijklnmopqrstuvwxyz");
ic.ItemsSource = btns;
RandomWord();
ChangeWord(SelEng, SelWord);
WrongStatus = $"틀린횟수: {wrong} of {maxWrong}";
}
private void ChangeWord(string selEng, List<char> selWord)
{
char[] result = selEng.Select(x => (selWord.IndexOf(x) >= 0 ? x : '*')).ToArray();
SelEng = string.Join(' ', result);
}
private void RandomWord()
{
string[] selChar = words[new Random().Next(0, words.Count)].Split(",");
SelEng = selChar[0];
SelKor = selChar[1];
compareWord = selEng;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
wrong = 0;
SelWord = new List<char>();
RandomWord();
ChangeWord(SelEng, SelWord);
Message = "알파벳을 선택하여 주세요";
Status();
foreach (var a in ic.Items)
{
var btn = (UIElement)ic.ItemContainerGenerator.ContainerFromItem(a);
if (btn != null)
{
btn.IsEnabled = true;
}
}
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
if (btn != null)
{
var result = btn.Content.ToString();
CheckWord(result[0]);
}
}
private void CheckWord(char v)
{
if(SelWord.IndexOf(v) == -1)
{
SelWord.Add(v);
}
if(compareWord.IndexOf(v) >= 0)
{
ChangeWord(compareWord, SelWord);
CheckWin();
}
else if (compareWord.IndexOf(v) == -1)
{
wrong++;
Status();
CheckLose();
}
}
private void Status()
{
WrongStatus = $"틀린횟수: {wrong} of {maxWrong}";
}
private void CheckWin()
{
if (compareWord == SelEng.Replace(" ", ""))
{
Message = "You Win!";
MessageBox.Show("정답!");
foreach (var a in ic.Items)
{
var btn = (UIElement)ic.ItemContainerGenerator.ContainerFromItem(a);
if (btn != null)
{
btn.IsEnabled = false;
}
}
}
}
private void CheckLose()
{
if (wrong == maxWrong)
{
Message = "You Lost!";
foreach(var a in ic.Items)
{
var btn = (UIElement)ic.ItemContainerGenerator.ContainerFromItem(a);
if(btn != null)
{
btn.IsEnabled = false;
}
}
}
}
}
}
- 데이터를 바인딩하는 것에 주목해보자
- get, set property를 사용하면 앞 대문자를 사용해서 변수처럼 대입연산자 사용하듯이 게터 세터를 사용할 수 있다.
- 물론 위 예제처럼 set을 커스터마이징 할 수 있다.
- INotifyPropertyChanged는 인터페이스인데 데이터 컨텍스트가 수정되면 실행될 메서드를 구현한다.
- OnPropertyChanged 메서드를 구현했고 세터마다 이 메서드를 호출함으로서 변경사항을 바로 반영한다.
- ItemContainerGenerator.ContainerFromItem으로 가져온 Item을 UIElement로 형변환 한 뒤 다룰 수 있다.
- 기타 로직들은 이해만 해보자