안녕하세요.
저는 회사에서 동적 스키마구조를 가진 데이터를 다루는 프로그램을 개발하고 있습니다.
ChatGPT에게 문의해본 결과, 동적 스키마를 갖고 있는 데이터를 다루는 .NET에서 다루는 방법은 DataTable, JObject, ExpendoObject, Dictionary 이렇게 4가지가 있다고 합니다.
그 중에서 DataTable이 가장 무겁기는 하나, Memory에 Load된 이후에 데이터를 다룰 때는 가장 편리하기 때문에 DataTable을 사용하기로 했습니다.
DataGrid.ItemsSource 에 DataTable을 Binding하고 AutoGenerateColumn = True를 하면 Column도 자동생성해주면서, 데이터도 모두 보일 것입니다.
단순하게 이것을 원하는 것은 아닙니다.
Cell마다 값을 판단하여 Style을 다르게 가져가고 싶습니다.
현재하고 있는 프로젝트는 제가 최선을 다해서 MVVM을 지키는 프로젝트입니다.
그러면 바인딩 되는 Cell Value를 판단하는 코드는 View가 아닌 ViewModel에 존재해야합니다.
ItemsSource가 되는 DataTable도 ViewModel에 있습니다.
Converter를 사용할 경우, Converter는 WPF에 해당하는 FCL이므로, Converter Class를 정의할 때 Binding되는 ViewModel의 Class를 참조해야합니다.
Class를 참조한다는 것은, Namespace를 참조해야한다는 뜻이고, Namespace를 참조한다는 것은 다른 프로젝트에 있다면 프로젝트도 참조를 걸어야 한다는 뜻입니다.
class를 참조해야 거기에 있는 소스코드를 converter에서 이용할 수 있으니까요.
순수한 WPF의 기능이 제가 만든 Boilerplate의 Model을 참조하는 형태가 됩니다.
저는 이 부분이 MVVM을 완벽하게 지키지 못하는 부분이라고 생각하는 쪽이기 때문에 Converter를 이용하면 매우 쉽겠지만 그렇게 하지 않고 다른 방법을 찾는 중에 있습니다.
그래서 ChatGPT가 추천해준 방법은, DataGrid.ItemsSource에 DataTable을 Binding 하지말고, Dictionary형태로 변환해서 바인딩하라고 합니다.
Dictionary의 Key값은 ColumnName이 되고, Value값은 실제 값과 Style 값이 들어있는 Class가 될 것입니다.
그리고 Dictionary자체가 하나의 Row가 될테니, DataTable은 2차원 배열형태이므로, Dictionary를 한번더 감싸주어야 합니다.
아래와 같을 것입니다.
public partial class CellItem : ObservableObject
{
[ObservableProperty]
public string cellValue;
[ObservableProperty]
public string background;
}
public partial class RowItem : ObservableObject
{
[ObservableProperty]
public Dictionary<string, CellItem> row;
}
public partial class ViewModel : ObservableObject
{
public ViewModel
{
Source = new();
}
[ObservableProperty]
ObservableCollection<RowItem> source;
}
따라서 XAML에서는
<DataGrid ItemsSource={Binding Source}
AutoGenerateColumn=True
.../>
위와 같이 될 것입니다.
그러나, 이렇게 하면 AutoGenerateColumn 기능으로 Column을 만들어주는 규칙을 위반하는 것이기 때문에 저의 의도대로 코드가 동작하지 않습니다.
위와 같은 코드는 DataGrid가 Column을 만들면 Row라는 Column을 1개 만들어 줄 것입니다.
아니면 오류가 나거나요. 아직 해보지는 않았습니다.
이 때 Column을 Generate해주는 이벤트를 MVVM을 헤치지 않으면서 View쪽에서 정의할 수 있을까요?
Dictionary의 key값을 참고해서 Column을 Generate하고, 그 Generate된 Column들은 위의 CellItem.Background Property를 참고해서 안에 ‘#FF123456’ 같은 hex값이 들어있다면 Converter를 이용해서 SoildColorBrush로 바꿔주고 싶습니다. (View단에서 CellItem을 참조하지 않고 이게 되는지도 모르겠습니다.)
이게 가능한것지 확신들지 않습니다…
혹시 경험이 있으신 분이 계시다면 고견 부탁드리겠습니다.
읽어주셔서 감사합니다.