Check된 CheckBox의 Content를 저장하여 TextBlock에 보여준다.
xaml 코드)
<Grid>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<GroupBox Grid.Row="0" x:Name="CheckBoxGroup" Header="그룹 박스">
<Grid HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<CheckBox x:Name="choose1" Grid.Row="0" Content="선택1"/>
<CheckBox x:Name="choose2" Grid.Row="1" Content="선택2"/>
<CheckBox x:Name="choose3" Grid.Row="2" Content="선택3"/>
</Grid>
</GroupBox>
<Button x:Name="chooseBtn" Grid.Row="1" Content="선택"/>
<TextBlock x:Name="Content" Grid.Row="2" Width="200"/>
</Grid>
</Grid>
GroupBox와 CheckBox 컨트롤, 선택한 CheckBox의 Content를 보여줄 TextBlock의 x:Name을 지정해주어야 한다.
ViewModel에서 지정한 x:Name을 통해 Content를 가져올 것이기 때문이다.
public partial class Page6 : Page
{
private static Page6 _Instance = null;
public static Page6 GetInstance()
{
if (_Instance == null || !_Instance.IsLoaded)
{
_Instance = new Page6();
}
return _Instance;
}
public Page6()
{
InitializeComponent();
_Instance = this;
}
}
ViewModel에서 선택 버튼을 누르면 TextBlock에 내용을 보여주는 Command를 작성한다.
chooseCheckBox에 로직을 작성하기 위해 TextBlock에 바인딩 할 데이터를 선언한다.
싱글톤으로 만든 View의 인스턴스를 호출하고 x:Name으로 지정한 컨트롤에 접근하여 내용을 가져오는데,
.FindLogicalChildren<>() 메소드는 Xceed WPF Toolkit을 설치해야 사용할 수 있다.
CheckBoxGroup이라는 x:Name을 가진 GroupBox 트리 내의 CheckBox 컨트롤들을 CheckBox 타입의 checkBox에 담고 if문에서 IsChecked가 True인 CheckBox의 Content를 string 변수 cb에 담은 후 cbStr에 이어붙인다.
ViewModel 코드)
internal class Page6ViewModel : BaseViewModel
{
public ICommand chooseCheckBoxCommand { get; set; }
public List<string> checkBoxList = new List<string>();
private string _checkBoxText { get; set; }
public string CheckBoxText
{
get { return _checkBoxText; }
set
{
_checkBoxText = value;
OnPropertyChanged(nameof(CheckBoxText));
}
}
public Page6ViewModel()
{
chooseCheckBoxCommand = new RelayCommand(chooseCheckBox);
}
private void chooseCheckBox()
{
Page6 page6 = Page6.GetInstance();
string cb = "";
string cbStr = "";
foreach(CheckBox checkBox in page6.CheckBoxGroup.FindLogicalChildren<CheckBox>())
{
if(checkBox.IsChecked == true)
{
cb = checkBox.Content.ToString();
cbStr += cb;
}
}
CheckBoxText = cbStr;
}
}
문자열을 이어붙여 하나의 string 변수에 담는게 아니라 나눠서 저장하고 싶다면 List를 사용하면 된다.
사실 다른 프로젝트를 하면서 먼저 Xceed Wpf ToolKit을 설치해 뒀었기 때문에 아무 생각없이 FindLogicalChildren...메소드를 사용했었다. 그러다 기록을 위해 연습용 솔루션에서 똑같이 작성하려고 하니 자동완성으로 저 메소드가 생기질 않아 난감해했었다. 찾아보니 그제야 Xceed Wpf ToolKit에서 제공하는 메소드였던 것임을 알게 되었다...
ToolKit을 설치하지 않고도 선택한 CheckBox의 Content의 값을 가져오는 방법이 분명 있을텐데 왜 못찾았을까?? 구글링도...스스로 생각해보는 힘도 둘 다 모자란 것 같다...
ViewModel에서 View 인스턴스를 참조하는 것은 MVVM 패턴에 반하는 방식입니다. 본문의 경우에는 체크박스에 바인딩할 Command를 만들고 각각의 체크박스에서 CommandParameter를 통해 해당 컨트롤의 Content를 ViewModel에 전달하는 것이 View와 ViewModel의 결합을 더 느슨하게 만드는 방식입니다. 더불어 Xceed Wpf Toolkit보다 Microsoft Community Toolkit 혹은 Prism Library를 사용해보면 MVVM 패턴을 활용하는데 도움될 것 같습니다.