簡體   English   中英

綁定列表<list<object> > 到代碼隱藏中的 DataGrid 列</list<object>

[英]Binding List<List<object>> to DataGrid columns in code-behind

我在將 List<List> 綁定到代碼隱藏中的 DataGrid 列時遇到問題。 這是我的清單:

private List<List<object>> matrix = new List<List<object>>()
     {
         new List<object>(){53, 2500, 3000, 3500, 4000, 4500, 5000},
         new List<object>(){2500, 1, 0, 0, 0, 0, 0},
         new List<object>(){3000, 0, 1, 0, 0, 0, 0},
         new List<object>(){3500, 0, 0, 1, 0, 0, 0},
         new List<object>(){4000, 0, 0, 0},
         new List<object>(){4500, 0, 0, 0, 0, 1, 0},
         new List<object>(){5000, 9, 7, 5, 4, 1, 1},
         new List<object>(){1, 0, 0, 0, 0, 0, 0},
         new List<object>(){2, 0, 0, 0, 0, 0, 0},
         new List<object>(){0, 0, 0, 0, 0, 0, 0}
     };

    public List<List<object>> Matrix
    {
        get { return matrix; }
        set
        {
            matrix = value;
            OnPropertyChanged(nameof(Matrix));
        }

我在 XAML 中這樣做是這樣的:

<DataGrid ItemsSource="{Binding Matrix}" VerticalAlignment="Top" FontSize="14" x:Name="matrixDataGrid" Height="420" Width="630" MinRowHeight="20" AutoGenerateColumns="False" >
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=[0], Mode=TwoWay}"/>
            <DataGridTextColumn Binding="{Binding Path=[1], Mode=TwoWay}"/>
            <DataGridTextColumn Binding="{Binding Path=[2], Mode=TwoWay}"/>
            <DataGridTextColumn Binding="{Binding Path=[3], Mode=TwoWay}"/>
            <DataGridTextColumn Binding="{Binding Path=[4], Mode=TwoWay}"/>
            <DataGridTextColumn Binding="{Binding Path=[5], Mode=TwoWay}"/>
            <DataGridTextColumn Binding="{Binding Path=[6], Mode=TwoWay}"/>
            <DataGridTextColumn Binding="{Binding Path=[7], Mode=TwoWay}"/>
            <DataGridTextColumn Binding="{Binding Path=[8], Mode=TwoWay}"/>
            <DataGridTextColumn Binding="{Binding Path=[9], Mode=TwoWay}"/>
        </DataGrid.Columns>
    </DataGrid>

這是結果: XAML 綁定的結果

我會稱之為半工作。 第一個問題是一個額外的行和 3 個額外的列。 第二個是如果我想要 1000 列,我將有很多工作要做。 還有很多 XAML binding errors: Binding errors 而且我什至不知道這個特定的綁定是如何工作的,看起來很奇怪。 我會很高興的解釋。

我在代碼隱藏中嘗試執行此操作的失敗嘗試如下所示:

Binding binding = new Binding();
binding.Source = Matrix; 
binding.Path = new PropertyPath("[0]"); 
binding.Mode = BindingMode.TwoWay;
columnOne.Binding = binding;

XAML 目前檔案:

<DataGrid ItemsSource="{Binding Matrix}" VerticalAlignment="Top" FontSize="14" x:Name="matrixDataGrid" Height="420" Width="630" MinRowHeight="20" AutoGenerateColumns="False" >
        <DataGrid.Columns>
            <DataGridTextColumn Width="50" x:Name="columnOne" />
        </DataGrid.Columns>
    </DataGrid>

我只得到空列: result of attempt 我見過有人用 DataTable 這樣做,但如果可能的話,我想按照我想要的方式來做。

我不會弄亂DataGrid ,這太麻煩了,除非您需要DataGrid的特定功能,如可排序的標題、分組等DataGrid也不能很好地處理巨大的矩陣,因為每個單元格在 UI 方面都非常笨重。

相反,由於您有一個ListList ,您可以使用ItemsControlItemsControl做同樣的事情。 只要每個元素具有相同的高度/寬度,那么它看起來就像DataGrid一樣。 您可以通過固定每個元素的大小來做到這一點,或者將ItemsPanel設置為強制大小一致的東西(如UniformGrid )。

要使綁定起作用以便單元格可編輯,您需要將每個矩陣單元格中的值包裝在實現 INotifyPropertyChanged 的內容中。

public class ItemViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler? PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string p = null) 
        => PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(p));
      
    private int _value;
    public int Value
    {
        get => _value;
        set
        {
           _value = value;
           OnPropertyChanged();
        }
    }

    public static implicit operator int(Item i) => i.Value;
    public static implicit operator Item(int i) => new () { Value = i};

    public static int[] GetArray(IEnumerable<Item> input) 
        => input.Select(i => i.Value).ToArray();

    public static int[][] GetMatrix(IEnumerable<IEnumerable<Item>> input) 
        => input.Select(ToArray).ToArray();
}

這是從 ItemsControl 派生的 MatrixGrid 的 XAML。 除了自動生成的構造函數之外,后面的代碼沒有任何內容。

<ItemsControl x:Class="WpfApp1.MatrixGrid" x:Name="ic"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              ItemsSource="{Binding}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ItemsControl ItemsSource="{Binding}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Columns="{Binding ElementName=ic, Path=ItemsSource.Count}"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"
                                 TextAlignment="Center"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

演示:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApp1">
    <local:MatrixGrid x:Name="matrixGrid"/>
</Window>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        matrixGrid.ItemsSource = Matrix;
    }

    public List<List<ItemViewModel>> Matrix { get; } = new List<List<Item>>()
    {
        new (){53, 2500, 3000, 3500, 4000, 4500, 5000},
        new (){2500, 1, 0, 0, 0, 0, 0},
        new (){3000, 0, 1, 0, 0, 0, 0},
        new (){3500, 0, 0, 1, 0, 0, 0},
        new (){4000, 0, 0, 0},
        new (){4500, 0, 0, 0, 0, 1, 0},
        new (){5000, 9, 7, 5, 4, 1, 1},
        new (){1, 0, 0, 0, 0, 0, 0},
        new (){2, 0, 0, 0, 0, 0, 0},
        new (){0, 0, 0, 0, 0, 0, 0}
    };
}

在此處輸入圖像描述

這樣做的好處是不需要隱藏代碼或以編程方式生成綁定。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM