Как использовать имена переменных в качестве заголовка столбца для DataGridView, когда имя переменной известно только во время выполнения? - PullRequest
0 голосов
/ 19 сентября 2018

Предисловие

Не уверен, что это имеет значение, но я объясню, как структурирован мой проект.Он имеет три слоя:

  • нативный C ++: цель состоит в том, чтобы прочитать несколько файлов и выполнить вычисления.Выходными данными являются числа типа double и векторы.

  • C ++ / CLI Wrapper: Уровень связи между моей родной программой C ++ и графическим интерфейсом C #.Он также преобразует мои собственные векторы C ++ в универсальные списки.

  • C #: этот слой используется для разработки графического интерфейса пользователя и в основном просто для представления результатов в диаграммах и таблицах.


Моя цель

Моя цель - заполнить DataGridView моими параметрами из class Evaluation в качестве столбца и значениями каждого проанализированного файла какстрока.

То, что я до сих пор делал, это:

  • Создание class Evaluation с каждым параметром в качестве свойства

    public ref class Evaluation 
    {     
     /.../ constructor exists
    
         System::Collections::Generic::List<double> ^GetTAFValues();
         System::Collections::Generic::List<double> ^GetTAFTemps();
    
         property double parameterA
         {
            double get() { return getParameterA(); }
         }
    
         property double parameterB
         {
            double get() { return getParameterB(); }
         }
     /.../
    }
    
  • Для каждого проанализированного файла (используя цикл foreach) я бы создал новый объект Evaluation и добавил бы этот объект в список с именем results типа List<Evaluation>

  • После этого я бы связал List<Evaluation> с DataGridView, выполнив dataGridView1.DataSource = results;

Пока это работает довольно хорошо, но только для параметров A и B. Чего мне не хватаетмой параметр TAF.

TAF состоит из температуры и значения.Например:

List<double> TAFValues =  new List<double> {1, 2, 3, 4};
List<double> TAFTemps = new List<double> {-30, -10, 25, 50,};

Мне нужно добавить столбцы с именами TAF-30, TAF-10, TAF25, TAF50 со значениями, добавленными от TAFValue.Эти четыре параметра могут быть использованы для всех оставшихся файлов.

Я не могу добавить TAF как свойство, хотя, потому что я не знаю, сколько температурных шагов используется во время компиляции и какое имя свойства (читай:какая температура) будет.

Вопросы / Идеи:

  • Как добавить столбцы, содержащие температурные строки, как HeaderText?

  • Можно ли как-нибудь объединить мой List<Evaluation> с моим List<double> и использовать его в качестве источника данных?Я знаю, что вам нужно создать список, но я не могу объявить переменные класса.

  • Могу ли я вручную вставить столбцы TAF + значения для каждой строки /file ПОСЛЕ того, как DataSource был объявлен с dataGridView1.DataSource = results;?

  • Существуют ли какие-либо другие структуры данных, которые я мог бы использовать в качестве источника данных вместо List, которые могли бы мне помочь?

Ответы [ 2 ]

0 голосов
/ 30 сентября 2018

У меня были те же проблемы, вот мое решение ... передача списка имен заголовков

    public void dgv_SetHeaderNames(DataGridView dgv, List<string> colNames, bool withColNum = false)
    {
        foreach (DataGridViewColumn dgvCol in dgv.Columns)
        {
            int currCol = dgvCol.Index;
            string colText = "";
            if (currCol >= colNames.Count)
            {
                // if there are more columns than name we will use the column number, anyway.
                colText = currCol.ToString();
            }
            else
            {
                if (withColNum == true)
                {
                    colText = currCol.ToString() + " - " + colNames[currCol];
                }
                else
                {
                    colText = colNames[currCol];
                }
            }
            dgv.Columns[currCol].HeaderText = colText;
        }
    }

Единственная проблема, с которой я столкнулся, в VS2017, я получаю IDE0028 для моей инициализации.

Но, как вы можете видеть, я повторно использую список для нескольких DataGridViews в моем проекте ...

        List<string> colNames = new List<string>();
        colNames.Add("Desc");
        colNames.Add("Freq");
        colNames.Add("Date");
        colNames.Add("Amount");
        colNames.Add("Pay From");
        dgv_SetHeaderNames(dgvDebits, colNames);
        dgvDebits.ColumnCount = colNames.Count;
        colNames[4] = "Type";
        dgv_SetHeaderNames(dgvIncome, colNames);
        dgvIncome.ColumnCount = colNames.Count;

        colNames.Clear();
        colNames.Add("Key");
        colNames.Add("Description");
        colNames.Add("Date");
        colNames.Add("Freq");
        colNames.Add("Amount");
        colNames.Add("Pay From");
        colNames.Add("USAA Checking");
        colNames.Add("Amazon VISA");
        dgv_SetHeaderNames(dgvWorking, colNames);

Мне кажется, я предпочитаю простоту VS2010!

Еще один приятныймаленькая хитрость, которую я узнал, это использование списка для заполнения заданной строки ...

dgvWorking.Rows.Add(wList.ToArray());

Я не нашел ни одного примера, чтобы сделать то же самое с заголовками ...

0 голосов
/ 20 сентября 2018

Мне удалось решить мою проблему с помощью Dictionary<string, object> и DataTable.Я думаю, чтобы решить мою проблему, используя свойства класса, мне нужно было бы реализовать Reflections, чтобы определить свойства во время выполнения.

Этот маршрут не требует отражений.Значения температуры для TAZ известны после первого запуска Calculate().Параметры применимы ко всем оставшимся файлам.


  • Первый шаг: Вместо сохранения моих параметров в качестве свойств класса и связывания его с DataGridView,Я решил использовать Dictionary<string, object> для хранения своих параметров.Поскольку Dictionary хранит string, я смог объявить имена динамических столбцов, выполнив "TAZ" + temperature.ToString() (temperature является vector<int>).

    // C++/CLI Wrapper file
    using namespace System::Collections::Generic;
    
    Dictionary<String^, Object^>^ EvaluationCLI::GetParameters()
    {
        Dictionary<String^, Object^>^ d = gcnew Dictionary<String^, Object^>();
        List<int>^ temps = GetTAFTemps();
        List<double>^ TAZ = GetTAZValues();
    
        d->Add("Parameter A", GetParameterA());
        d->Add("Parameter B", GetParameterB());
    
        for (int i = 0; i < temps->Count; i++)
        {
            d->Add("TAZ_" + temps[i].ToString(), TAZ[i] );
        }
        return d;
    }
    
  • Второй шаг: Вместо использования свойств из Evaluation и добавления их к List<Evaluation>, я бы использовал Dictionary<string, object> и заполнил DataTable как DataSource.

    * 1034.*

Результаты:

  • A DataGridView с именами параметров времени выполнения в виде столбцов
  • Каждая строка представляетновый файл / оценка
  • Значения строк соответствуют столбцам параметров

    |---------------------|------------------|------------------|------------------|
    |     Parameter A     |    Parameter B   |       TAZ_10     |       TAZ_50     |
    |---------------------|------------------|------------------|------------------|
    |          12         |         26       |         96       |         89       |
    |---------------------|------------------|------------------|------------------|
    |          85         |         34       |         91       |         72       |
    |---------------------|------------------|------------------|------------------|
    |         ...         |        ...       |        ...       |        ...       |
    |---------------------|------------------|------------------|------------------|
    
...