2015-09-17 4 views
0

Так что я пытаюсь изменить текст из проекта WinForms из другого класса, кроме класса Form. Он должен работать так:C# Как изменить/получить доступ к элементам управления WinForms из другого класса

right

Но вместо этого он делает это:

wrong

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

Я использую этот метод, чтобы изменить прогрессбар:

public void IncreaseProgress(int progBarStepSize, String statusMsg, int currentProject=-1) { 
    if (currentProject != -1) { 
     lblStatus.Text = String.Format("Status: {0} | project {1} of {2}",statusMsg,currentProject,ProjectCount); 
    } 
    else { 
     lblStatus.Text = String.Format("Status: {0}",statusMsg); 
    } 

    pb.Increment(progBarStepSize); 
} 

А вот где я использую метод:

public void InitialiseFile(List<string> filePaths, int eurojobType) 
{ 
    foreach (string sheet in outputSheets) { 
     switch (sheet) { 
      case "Summary": 
       for (int i = 0; i < filePaths.Count; i++) { 
          var filePath = filePaths[i]; 
        IncreaseProgress(1, "Reading Summary", i); 
        worksheetIn = excelReader.ReadExcelSummary(filePath); 

        IncreaseProgress(1, "Writing Summary", i); 
        excelWriter.WriteExcelSummary(worksheetIn); 
       } 
       break; 
      case "Monthly_Cat1": 
       for (int i = 0; i < filePaths.Count; i++) { 
        var filePath = filePaths[i]; 
        IncreaseProgress(1, "Reading Monthly", i); 
        worksheetIn = excelReader.ReadExcelMonthly(filePath); 

        IncreaseProgress(1, "Writing Monthly", i); 
        excelWriter.WriteExcelMonthly(worksheetIn); 
       } 
       break; 
     } 
    } 
    IncreaseProgress(1, "Completed!"); 
} 

Теперь я знаю, этот код работает, потому что приращения ProgressBar. И он должен прыгать в первом if-loop, потому что i передается как параметр, который никогда не -1.

//manager class 
private Label lblStatus; 
private ProgressBar pb; 

public Manager(ProgressBar pb, Label lbl){ 
    this.pb = pb; 
    lblStatus = lbl; 
} 

//Form class 
Manager mgr = new Manager(progressBar1, lblStatus, projectFilePaths.Count, outputSheets.ToArray(), exportPath); 
mgr.InitialiseFile(projectFilePaths, eurjobType); 
+5

Не делайте блокировки работы с потоком пользовательского интерфейса. – SLaks

+0

Эдвард, найдите момент, чтобы просмотреть «Задачи» и «Асинхронный шаблон»; а также интерфейс 'IProgress ' –

+0

@SLaks, что именно вы имеете в виду? Весь метод mgr.InitialiseFile() должен находиться в фоновой работе, чтобы пользовательский интерфейс не нуждался в том, чтобы дождаться завершения этого метода? – Edward

ответ

1

Вы можете вызвать lblStatus.Refresh();, чтобы заставить управление перерисовывать, после установки его Text. Но рассмотрим Slaks комментарий:

Не делать блокирование работы в потоке пользовательского интерфейса

Вы можете рассмотреть возможность использования BackgroundWorker или Task.Run или асинхронный/ждать шаблон вместо.

В качестве примера:

private async void button1_Click(object sender, EventArgs e) 
{ 
    await Task.Run(() => 
    { 
     for (int i = 0; i < 10000; i++) 
     { 
      this.Invoke(new Action(() => 
      { 
       label1.Text = i.ToString(); 
       label1.Refresh(); 
      })); 
     } 
    }); 
} 

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

Вы должны поместить коды, связанные с UI, в действие, инициированное Invoke, чтобы исключить возможность исключения перекрестной резьбы.

+0

Я принимаю это как aswer, как 'lblStatus.Refresh();' работал. Но я вижу заботу об использовании фонового работника, потому что форма замораживает выполнение нескольких файлов, как сказал Слэкс. – Edward

+0

@Edward Итак, используйте образец кода в тестовой форме и посмотрите результат. Вы можете перемещать форму, сворачивать, максимизировать, нажимать на другие кнопки и т. Д., Не замораживая форму. На самом деле код в 'Task.Run' работает в другом потоке, чем поток пользовательского интерфейса. –

+0

@Edward вы можете видеть это [ответ] (http://stackoverflow.com/a/32620833/3110834) тоже. –

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