[英]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 方面都非常笨重。
相反,由於您有一個List
的List
,您可以使用ItemsControl
的ItemsControl
做同樣的事情。 只要每個元素具有相同的高度/寬度,那么它看起來就像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.