문제

나는 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>

그리고 뒤에있는 코드에서는 두 가지 예측 데이터 구조로 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_Level2를 편집하여 객체의 특정 데이터를 추가 할 수 있습니다.

alt text

다른 팁

다음은 컨트롤이 있습니다 DataGrid2D 2D 또는에 따라 채워질 수 있습니다
1D 배열 (또는 구현하는 모든 것 IList 상호 작용). 서브 클래스 DataGrid 호출되는 속성을 추가합니다 ItemsSource2D 2D 또는 1D 소스에 대한 결합에 사용됩니다. 라이브러리를 다운로드 할 수 있습니다 여기 소스 코드를 다운로드 할 수 있습니다 여기.

사용하려면 DataGrid2dlibrary.dll에 대한 참조를 추가하면이 네임 스페이스를 추가하십시오.

xmlns:dg2d="clr-namespace:DataGrid2DLibrary;assembly=DataGrid2DLibrary"

그런 다음 DataGrid2d를 작성하여 ILIST, 2D 배열 또는 이와 같은 1D 배열에 바인딩하십시오.

<dg2d:DataGrid2D Name="dataGrid2D"
                 ItemsSource2D="{Binding Int2DList}"/>

enter image description here


오래된 게시물
다음은 2D 배열을 WPF Datagrid에 바인딩 할 수있는 구현입니다.

이 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); } }  
} 

그런 다음 2D 배열을 가져 와서 위의 Ref 클래스를 사용하여 데이터 뷰를 반환 할 수있는 메소드로 정적 헬퍼 클래스를 만들었습니다.

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;
}

이것은 거의 결합하기에 충분하지만 바인딩의 경로는 우리가 필요로하는 ref.value 대신 심판 객체를 가리므로 열이 생성 될 때 이것을 변경해야합니다.

<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);

그리고 출력은 다음과 같습니다

alt text

모든 변경 사항 DataGrid m_intarray에 반영됩니다.

나는 작은 부동산의 작은 라이브러리를 썼다. DataGrid. 여기 소스가 있습니다

샘플, 여기서 data2d int[,]:

<DataGrid HeadersVisibility="None"
          dataGrid2D:Source2D.ItemsSource2D="{Binding Data2D}" />

렌더 :enter image description here

이 링크를 확인할 수 있습니다. http://www.thinkbottomup.com.au/site/blog/game_of_life_in_xaml_wpf_using_embedded_python

목록 내에서 목록을 사용하는 경우 mylist [x] [y]를 사용하여 셀에 액세스 할 수 있습니다.

다음은 다른 솔루션을 기반으로합니다 Meleak대답이지만 필요하지 않습니다 AutoGeneratingColumn 각 binde의 뒤에 코드의 이벤트 핸들러 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;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top