WPF에서 MVVM 패턴 사용시 데이터그리드 내 Column에 값을 Binding할때 보통 어떻게 하시나요?
<Datagrid ItemsSource="{Binding SetList}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ElementName=Id}" />
<DataGridTextColumn Binding="{Binding ElementName=Name}" />
<DataGridTextColumn Binding="{Binding ElementName=Part}" />
</DataGrid.Columns>
</Datagrid>
보통 이런 식으로 데이터 그리드의 각 Column마다 바인딩을 해준 후 ViewModel 쪽에 클래스를 생성해주는 게 일반적일텐데요

public class ItemSet : BindableBase
{
private int id = 0;
public int ID
{
get => id;
set => SetProperty(ref id, value);
}
private string name = "";
public string Name
{
get => name;
set => SetProperty(ref name, value);
}
private string part = "";
public string Part
{
get => part;
set => SetProperty(ref part, value);
}
}
예를 들어 이런 식으로 클래스를 생성하고
private ObservableCollection<ItemSet> setList = new ObservableCollection<ItemSet>();
public ObservableCollection<ItemSet> SetList
{
get => setList;
set => SetProperty(ref setList, value);
}
연결된 뷰모델 쪽에서 이렇게 해당 클래스의 ObservableCollection을 생성해주는 방식입니다.
그런데 이렇게 사용하게 되면 저희는 데이터그리드의 ItemsSource를 SetList로 정의해버렸기 때문에...!
SetList 내에 있는 속성, 즉 ItemSet 클래스 내에 있는 속성만 바인딩을 할 수 있게 됩니다.
예를 들어
private bool checkedAllSet = false;
public bool CheckedAllSet
{
get => checkedAllSet;
set =>SetProperty(ref checkedAllSet, value);
}
뷰모델 내에 있는 이 Property를 데이터그리드 내의 체크박스와 바인딩시키고 싶어서 체크박스에 IsChecked="{Binding CheckedAllSet} 를 해준다면 절대 적용되지 않는다는 말입니다.

이미 저희는 ItemsSource를 SetList로 적어놨기 때문에 그 안에서만 바인딩 값을 찾아버리거든요...
그래서 !!!!
뷰모델에 있는 값을 직접적으로 연결해주기 위해서는 RelativeSource 설정이 필요합니다.
Binding을 해줄때는 어디 있는 값을 바인딩할지 관련 소스를 설정해서 경로를 만들어줄 수가 있습니다
아래 코드를 보시죠 +__+
<수정 전>
IsChecked="{Binding CheckedAllSet}
<수정 후>
IsChecked="{Binding DataContext.CheckedAllSet,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl}}"
RelativeSource 내에는 Mode와 AncestorType이 있습니다.
Mode를 FindAncestor로 지정하게 되면 자신의 부모를 타고 올라가게 됩니다.
저는 데이터그리드 내에 있는 체크박스에 바인딩을 했으니 체크박스 => 데이터그리드 => 스택패널 => 그리드 => 유저컨트롤 이런식으로 자신을 감싸고 있는 부모를 찾아가게 되는데요
AncestorType을 UserControl로 지정해줬으므로 체크박스를 감싸고 있는 UserControl이 요 체크박스 바인딩의 소스로 설정이 됩니다.
그러고 나서 DataContext.CheckedAllSet 을 바인딩하게 되면 UserControl의 DataContext인 해당 뷰모델에서 CheckedAllSet을 찾게 됩니다.
저희가 CheckedAllSet이 어디에 위치해있는지 경로를 만들어준 거라고 볼 수 있죠
이렇게 코드를 바꿔주면 바인딩이 아주 잘 되는걸 볼 수 있습니다
데이터그리드 내에 ItemsSource 내부 값이 아닌 다른 값을 바인딩하실 때 참고하시면 좋을것 같아요

아직 모르는 부분이 많아 위 내용에 잘못된 점이 있다면 댓글로 피드백 달아주세요!
참고해서 적극적으로 수정하겠습니다. 감사합니다.
'C# > WPF' 카테고리의 다른 글
StaticResourceHolder 값 제공 예외 throw (0) | 2022.02.14 |
---|---|
Array Binding 시 Property Changed 이벤트 (0) | 2022.02.08 |
WPF Binding된 이미지 파일 접근 시 사용중 Exception (0) | 2022.02.07 |