2016-12-17 2 views
-1

У меня есть несколько объектов NumericUpDown. Мне нужно сохранить все их значения в соответствующие переменные (в свойствах). Я установил его с помощью цикла, поэтому он короче, но он не работает.Использовать переменные как часть имени с петлями

Это код:

private void RefreshTimer_Tick(object sender, EventArgs e) 

for (int Count = 11; Count <= 16; Count++) 
{ 
    Properties.Settings.Default.("_NW" + Count) = this.Controls.("NW" + Count).Value; 
    Properties.Settings.Default.Save; 
} 

Длинный код должен выглядеть следующим образом:

 Properties.Settings.Default._NW11 = NW11.Value; 
     Properties.Settings.Default._NW12 = NW12.Value; 
     Properties.Settings.Default._NW13 = NW13.Value; 
     Properties.Settings.Default._NW14 = NW14.Value; 
     Properties.Settings.Default._NW15 = NW15.Value; 
     Properties.Settings.Default._NW16 = NW16.Value; 
     Properties.Settings.Default.Save(); 

, но слишком долго, поэтому я хочу, чтобы использовать цикл.

Что случилось?

+2

«это не работает» не является адекватным описанием проблемы. Пожалуйста, укажите, в чем проблема. – Dai

+1

'По умолчанию. (" _ NW "+ Count)' - Что это за синтаксис? – David

+0

Properties.Settings.Default._NW + Значение счетчика -> это синтаксис, указывающий на переменную, где нужно поместить значение NumericUpDown. NumericUpDown - NW + значение счета. На самом деле я заметил, что в коде есть некоторые ошибки из-за копирования и вставки без перечитывания (извините). – tutorialinformation

ответ

0

Если кто-то имеет такую ​​же проблему: Код работает Просто Напомните Включить таймер ...

Код:

private void RefreshTimer_Tick(object sender, EventArgs e) 
    { 
     for (int Count = 11; Count <= 16; Count++) 
     { 
      Properties.Settings.Default.("_NW" + Count) = this.Controls.("NW" + Count).Value; 
      Properties.Settings.Default.Save(); 
     } 
    } 
0

Вы можете использовать отражение. Нечто подобное (не проверено):

for (int Count = 11; Count <= 16; Count++) 
{ 
    var property = Properties.Settings.Default.GetType().GetProperty("_NW" + Count); 
    var value = this.Controls["NW" + Count].Value; 
    property.SetValue (Properties.Settings.Default, propertyValue, null); 
} 

Properties.Settings.Default.Save; 

Другие подходы, несут динамический объект как ExpandoObject для настройки, а затем, наконец, сохранить его Settings в одном кадре позже в какой-то момент. Кроме того, отражение свойств может быть сделано быстрее с использованием деревьев выражений.

+0

ошибка: элемент управления не содержит определение значения ... – tutorialinformation

+0

Возьмите все, что у вас есть. Может быть «Text» ?. У вашего кода есть свойство «Значение», поэтому я его использовал. Независимо от того, что производит 'NW11.Value' и т. Д. – nawfal

+0

все еще есть некоторые проблемы ... и да NW11 обладает свойством Value ... – tutorialinformation

1

Если вы подумываете прибегнуть к отражению, всегда старайтесь найти больше вариантов.

Решение - это массивы/списки. Они предназначены для индексированного доступа, требования, которые вы пытаетесь выполнить. Но для этого вам необходимо перестроить существующие указатели ресурсов для инициализации и организации в таком массиве/списке.

1) Для ваших настроек используйте один System.Collection.Specialized.StringCollection, а не несколько отдельных параметров строки. Сделайте первые пустые.

2) Затем настройте элементы управления в массив.

List<Control> controlsArray = new List<Control>(); 
void FormLoad(...) 
{ 
    for (var i = 0; i < 11; i++) 
     controlsArray.Add(null); //Dummy values 

    controlsArray.Add(this.Controls.NW11); 
    controlsArray.Add(this.Controls.NW12); 
    controlsArray.Add(this.Controls.NW13); 
    controlsArray.Add(this.Controls.NW14); 
    controlsArray.Add(this.Controls.NW15); 
    controlsArray.Add(this.Controls.NW16); 
} 

3) Затем вы можете сделать это:

private void RefreshTimer_Tick(object sender, EventArgs e) 
{ 
    for (int Count = 11; Count <= 16; Count++) 
    { 
     if (controlsArray[Count] == null) 
      continue; //To be on the safe side 
     Properties.Settings.Default._NW[Count] = controlsArray[Count].Value; 
    } 
    Properties.Settings.Default.Save(); //Do this after the assignment loop has finished 
} 

4) Если у вас есть гораздо больше контроля, и необходимо повторить этот шаблон часто в вашем коде, то вы можете автоматизировать шаг [2] лучше.

List<Control> controlsArray = new List<Control>(); 
void FormLoad(...) 
{ 
    foreach (var control in this.Controls) 
    { 
     if (control.Name.StartsWith("NW") == false) 
      continue; 

     var numberString = control.Name.SubString(2, control.Name.Length - 2); 
     var controlNumber = int.Parse(numberString); 

     while (numberString > controlsArray.Count - 1) 
      controlsArray.Add(null); 

     controlsArray[controlNumber] = control; 
    } 
} 

Но для такой небольшой проблемы имеет смысл просто использовать свое длинное решение. Почему весь этот код (возможно, удваивает строки, а не так просто, чтобы следить за тем, что он делает - и почему), когда вы можете просто быть явным?

Это зависит от вас, чтобы решить.

Антибликовое Рант

И да, вы всегда должны стараться, чтобы избежать отражения.

Даже для сериализации/десериализации, ответ не является отражением.Вы можете создавать вспомогательные функции во время компиляции или даже генерировать прокси сериализации во время выполнения. Больше работы, конечно, но, конечно, лучше. Инструменты protobuf от Google генерируют файлы кода из файлов протокола во время разработки.

Даже для связи с существующими библиотеками. Например, вы можете использовать Mono.Cecil, чтобы преобразовать все частные интерфейсы в общедоступные во время выполнения, а затем напрямую ссылаться.

Надеюсь, вы поняли суть. У вас не всегда есть ресурсы, но это всегда решение best, когда вы можете избежать отражения.

0

Я пошел в другом форуме и задал тот же вопрос и правильный код (наиболее Простейшие) является:

private void Form1_Load(object sender, EventArgs e) 
    { 
     for (int Count = 11; Count <= 16; Count++) 
     { 
      ((NumericUpDown)(Controls["NW" + Count])).Value = (decimal)Properties.Settings.Default["_NW" + Count]; 
     } 
    } 

    private void RefreshTimer_Tick(object sender, EventArgs e) 
    { 
     for (int Count = 11; Count <= 16; Count++) 
     { 
      Properties.Settings.Default["_NW" + Count] = ((NumericUpDown)(Controls["NW" + Count])).Value; 
     } 
     Properties.Settings.Default.Save(); 
    } 

Это сохранит vlaues в переменных и загрузить значения в NumericUpDown при загрузке программы (или Form1).

Смежные вопросы