2차원 어레이를 기반으로 WPF 그리드를 채우는 방법
2차원 객체 배열이 있는데 기본적으로 각 객체를 WPF 그리드의 셀에 데이터 바인딩하고 싶습니다.현재 저는 이 일을 하고 있지만, 대부분의 일을 절차적으로 하고 있습니다.올바른 개수의 행 및 열 정의를 작성한 후 셀을 루프하여 컨트롤을 만들고 각각에 대해 올바른 바인딩을 설정합니다.
최소한 템플릿을 사용하여 컨트롤과 바인딩을 xaml로 지정할 수 있으면 좋겠습니다.이상적으로는 절차 코드를 없애고 데이터 바인딩으로 모든 것을 하고 싶은데, 그것이 가능한지 모르겠습니다.
현재 사용하고 있는 코드는 다음과 같습니다.
public void BindGrid()
{
m_Grid.Children.Clear();
m_Grid.ColumnDefinitions.Clear();
m_Grid.RowDefinitions.Clear();
for (int x = 0; x < MefGrid.Width; x++)
{
m_Grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star), });
}
for (int y = 0; y < MefGrid.Height; y++)
{
m_Grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star), });
}
for (int x = 0; x < MefGrid.Width; x++)
{
for (int y = 0; y < MefGrid.Height; y++)
{
Cell cell = (Cell)MefGrid[x, y];
SolidColorBrush brush = new SolidColorBrush();
var binding = new Binding("On");
binding.Converter = new BoolColorConverter();
binding.Mode = BindingMode.OneWay;
BindingOperations.SetBinding(brush, SolidColorBrush.ColorProperty, binding);
var rect = new Rectangle();
rect.DataContext = cell;
rect.Fill = brush;
rect.SetValue(Grid.RowProperty, y);
rect.SetValue(Grid.ColumnProperty, x);
m_Grid.Children.Add(rect);
}
}
}
그리드의 목적은 실제 데이터 바인딩이 아니라 패널입니다.2차원 리스트를 시각화할 수 있는 가장 쉬운 방법을 나열하고 있습니다.
<Window.Resources>
<DataTemplate x:Key="DataTemplate_Level2">
<Button Content="{Binding}" Height="40" Width="50" Margin="4,4,4,4"/>
</DataTemplate>
<DataTemplate x:Key="DataTemplate_Level1">
<ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource DataTemplate_Level2}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
</Window.Resources>
<Grid>
<ItemsControl x:Name="lst" ItemTemplate="{DynamicResource DataTemplate_Level1}"/>
</Grid>
그리고 뒤에 있는 코드에서 아이템을 설정합니다.TwoDimensional 데이터 구조의 lst 소스입니다.
public Window1()
{
List<List<int>> lsts = new List<List<int>>();
for (int i = 0; i < 5; i++)
{
lsts.Add(new List<int>());
for (int j = 0; j < 5; j++)
{
lsts[i].Add(i * 10 + j);
}
}
InitializeComponent();
lst.ItemsSource = lsts;
}
그러면 다음과 같은 화면이 출력됩니다.DataTemplate_를 편집할 수 있습니다.레벨 2: 객체의 특정 데이터를 추가합니다.
.DataGrid2D
로 설정할 수 .
어레이 1D를 것)IList
분류하다DataGrid
이 때 '아까워서'라는 .ItemsSource2D
2D 또는 1D 소스에 대한 바인딩에 사용됩니다.라이브러리는 여기서, 소스 코드는 여기서 다운로드할 수 있습니다.
DataGrid2에 대한 참조만 추가하면 사용할 수 있습니다.DLibrary.dll, 이 네임스페이스를 추가합니다.
xmlns:dg2d="clr-namespace:DataGrid2DLibrary;assembly=DataGrid2DLibrary"
그런 다음 DataGrid2D를 생성하여 IList, 2D 어레이 또는 1D 어레이에 바인드합니다.
<dg2d:DataGrid2D Name="dataGrid2D"
ItemsSource2D="{Binding Int2DList}"/>
WPF 데이터 그리드에 2D 어레이를 바인드할 수 있는 실장을 다음에 나타냅니다.
예를 들어 이 2D 어레이가 있다고 합시다.
private int[,] m_intArray = new int[5, 5];
...
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
m_intArray[i,j] = (i * 10 + j);
}
}
다음으로 이 2D 어레이를 WPF DataGrid에 바인드하고 변경 내용이 어레이에 반영됩니다.이를 위해 이 스레드에서 Eric Lippert의 Ref 클래스를 사용했습니다.
public class Ref<T>
{
private readonly Func<T> getter;
private readonly Action<T> setter;
public Ref(Func<T> getter, Action<T> setter)
{
this.getter = getter;
this.setter = setter;
}
public T Value { get { return getter(); } set { setter(value); } }
}
그리고 위의 Ref 클래스를 사용하여 2D 어레이를 사용하여 DataView를 반환할 수 있는 방법으로 정적 도우미 클래스를 만들었습니다.
public static DataView GetBindable2DArray<T>(T[,] array)
{
DataTable dataTable = new DataTable();
for (int i = 0; i < array.GetLength(1); i++)
{
dataTable.Columns.Add(i.ToString(), typeof(Ref<T>));
}
for (int i = 0; i < array.GetLength(0); i++)
{
DataRow dataRow = dataTable.NewRow();
dataTable.Rows.Add(dataRow);
}
DataView dataView = new DataView(dataTable);
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
int a = i;
int b = j;
Ref<T> refT = new Ref<T>(() => array[a, b], z => { array[a, b] = z; });
dataView[i][j] = refT;
}
}
return dataView;
}
이것은 바인딩하기에 충분하지만 바인딩의 경로는 참조가 아닌 참조 개체를 가리킵니다.열 생성 시 이 값을 변경해야 합니다.
<DataGrid Name="c_dataGrid"
RowHeaderWidth="0"
ColumnHeaderHeight="0"
AutoGenerateColumns="True"
AutoGeneratingColumn="c_dataGrid_AutoGeneratingColumn"/>
private void c_dataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
DataGridTextColumn column = e.Column as DataGridTextColumn;
Binding binding = column.Binding as Binding;
binding.Path = new PropertyPath(binding.Path.Path + ".Value");
}
그리고 이 후에 우리는
c_dataGrid.ItemsSource = BindingHelper.GetBindable2DArray<int>(m_intArray);
출력은 다음과 같습니다.
에서 변경된 사항DataGrid
m_intArray에 반영됩니다.
나는 작은 도서관의 부속물들을 썼다.DataGrid
출처는 이쪽입니다.
샘플, 여기서 Data2D는int[,]
:
<DataGrid HeadersVisibility="None"
dataGrid2D:Source2D.ItemsSource2D="{Binding Data2D}" />
렌더링:
여기 Mereak의 답변에 기초한 다른 솔루션이 있습니다. 단, 이 솔루션에는 Mereak의 답변이 필요 없습니다.AutoGeneratingColumn
바인드된 각 코드 뒤의 이벤트핸들러DataGrid
:
public static DataView GetBindable2DArray<T>(T[,] array)
{
var table = new DataTable();
for (var i = 0; i < array.GetLength(1); i++)
{
table.Columns.Add(i+1, typeof(bool))
.ExtendedProperties.Add("idx", i); // Save original column index
}
for (var i = 0; i < array.GetLength(0); i++)
{
table.Rows.Add(table.NewRow());
}
var view = new DataView(table);
for (var ri = 0; ri < array.GetLength(0); ri++)
{
for (var ci = 0; ci < array.GetLength(1); ci++)
{
view[ri][ci] = array[ri, ci];
}
}
// Avoids writing an 'AutogeneratingColumn' handler
table.ColumnChanged += (s, e) =>
{
var ci = (int)e.Column.ExtendedProperties["idx"]; // Retrieve original column index
var ri = e.Row.Table.Rows.IndexOf(e.Row); // Retrieve row index
array[ri, ci] = (T)view[ri][ci];
};
return view;
}
다음 링크를 확인해 주십시오.http://www.thinkbottomup.com.au/site/blog/Game_of_Life_in_XAML_WPF_using_embedded_Python
목록 내 목록을 사용하는 경우 myList[x][y]를 사용하여 셀에 액세스할 수 있습니다.
언급URL : https://stackoverflow.com/questions/276808/how-to-populate-a-wpf-grid-based-on-a-2-dimensional-array
'source' 카테고리의 다른 글
아이폰 앱에서 NSError를 사용하려면 어떻게 해야 하나요? (0) | 2023.04.12 |
---|---|
컴파일 경고: 아키텍처 i386의 파일을 처리하는 규칙이 없습니다. (0) | 2023.04.12 |
iOS UIView 컨트롤러의 라이프 사이클을 이해하려고 합니다. (0) | 2023.04.12 |
bash 스크립트가 실행 중일 때 출력을 파일로 강제 플러시합니다. (0) | 2023.04.12 |
WPF에서의 바인딩을 위한 내부 제어 속성 노출 (0) | 2023.04.12 |