UWP GridView с динамическими c именами столбцов - PullRequest
1 голос
/ 05 августа 2020

Я пытаюсь заполнить GridView некоторыми данными, но мне не повезло. Документация абсолютно ничего не говорит мне о том, как GridView отображает данные из источника элемента в строки в элементе управления. Я видел пример текстового поля, где они создают класс со свойствами, и это отлично работает:

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>

Но моя проблема в том, что имена столбцов просто неизвестно при компиляции, поэтому я не могу использовать этот подход. Мне нужно указать имена столбцов во время выполнения и сопоставить данные с указанными c столбцами, но здесь я застрял. Я не могу придумать, как это сделать. Я не могу найти никакой документации о том, как он отображает данные из набора данных в разные столбцы. Я могу в значительной степени догадываться, но мне это не помогает.

Я считаю, что весь этот подход к привязке данных ужасен, негибок, медленен и сложен в использовании. Почему невозможно просто использовать интерфейс для привязки данных вместо получения объектов?

Есть какие-нибудь подсказки о том, как этого добиться?

Решение: I определил класс DataView для использования в качестве источника элементов следующим образом:

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 будет содержать одну строку информации.

1 Ответ

1 голос
/ 06 августа 2020

Мне нужно указать имена столбцов во время выполнения и сопоставить данные с указанными c столбцами.

Если вы используете AutoGenerateColumns, столбцы header будет автоматически генерировать базу на основе имени свойства модели данных.

У вас есть много способов указать c заголовок столбца. Один из них - это c DataGridColumn в xaml с настраиваемым заголовком.

<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" />

Другой - найти свойство c DataGridColumn from DataGrid.Columns и отредактировать заголовок в коде позади .

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