具有列动态名称的 UWP GridView

UWP GridView with dynamic names for columns

我正在尝试用一些数据填充 GridView,但我没有成功。文档完全没有告诉我 GridView 如何将数据从项目源映射到控件中的行。我看过文本框示例,他们在其中创建了一个带有属性的 class,这很好用:

public sealed partial class CollectionInfoPage: Page
{
    List<Test> m_ItemSource;
    
    class Test
    {
        public string s1 => "Hello";
        public string s2 => "World";
    }

    public async Task ModelUpdated(Model.Adaptor Adaptor)
    {
        await Common.RunUiTask(async () =>
        {
            m_ItemSource = new List<Test> { new Test(), new Test() };
        });
    }
}

XAML:

<Page
    x:Class="CollectionInfoPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="Transparent">

    <Grid>
        <controls:DataGrid x:Name="DataGrid" AutoGenerateColumns="True" ItemsSource="{x:Bind m_ItemSource}">
        </controls:DataGrid>
    </Grid>
</Page>

但我的问题是列名在编译时根本不知道,所以我不能使用这种方法。我需要能够在运行时指定列的名称并将数据映射到那些特定的列,但这就是我遇到的问题。我想不出办法。我找不到任何关于它如何将数据从数据集映射到不同列的文档。我几乎可以猜到,但这对我没有好处。

我发现整个数据绑定方法很糟糕、不灵活、缓慢且难以使用。为什么不能简单地使用接口来进行数据绑定而不是获取对象?

关于如何实现这一目标的任何线索?

解法: 我定义了一个 DataView class 用作项目源,如下所示:

class DataView
{
    public IEnumerable<string> Data { get; }

    public DataView(IEnumerable<string> Data)
    {
        this.Data = Data;
    }
}

然后我使用代码创建列并创建到项目源中数据的绑定:

int n = 0;
var Cols = ColNames.Select((x, n) =>
{
    var Col = new DataGridTextColumn();
    Col.Header = x;
    Col.Binding = new Windows.UI.Xaml.Data.Binding();
    Col.Binding.Path = new PropertyPath("Data[" + n + "]");
    return Col;
}).ToList();

foreach (var Col in Cols)
    DataGrid.Columns.Add(Col);

XAML:

<Page
    x:Class="CollectionInfoPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="Transparent">

    <Grid>
        <controls:DataGrid x:Name="DataGrid" AutoGenerateColumns="False" ItemsSource="{x:Bind m_GridItemSource}"/>
    </Grid>
</Page>

然后我只需要设置我的项目源,其中每个 DataView 实例将包含一行信息。

I need to be able to specify the names of the columns at runtime and map the data to those specific columns.

如果您使用 AutoGenerateColumns,列 header 将根据数据模型的 属性 名称自动生成。

您可以通过多种方式来指定列 header。一个是特定于 xaml 中的 DataGridColumn 与自定义 header。

<controls:DataGridTextColumn Header="Rank" Binding="{Binding Rank}" Tag="Rank" />
<controls:DataGridTextColumn Header="Height (m)" Binding="{Binding Height_m}" Tag="Height_m" />
<controls:DataGridTextColumn Header="Range" Binding="{Binding Range}" Tag="Range" />
<controls:DataGridTextColumn Header="Parent Mountain" Binding="{Binding Parent_mountain}" Tag="Parent_mountain" />

另一种是从DataGrid.Columns属性中找到具体的DataGridColumn,然后在后面的代码中编辑header。

private void DataGrid_Loaded(object sender, RoutedEventArgs e)
{
    var colum = DataGrid.Columns[0] as DataGridColumn;
    colum.Header = "Test";
}