Autor |
Beitrag |
Oppi35
      
Beiträge: 95
Erhaltene Danke: 3
|
Verfasst: Fr 11.03.11 23:56
Hallo Zusammen,
ich habe in meiner Anwendung ein Hauptfenster und ein Fenster, dass lediglich eine Progressbar enthält.
Das Fenster mit der Progressbar rufe ich dann mit ...ShowDialog() auf.
Nur klappt jetzt das Update der Progressbar nicht mehr. Kann mir jemand sagen, wie ich in einem gestarteten modalen Dialogfeld Properties ändern kann?
Nur zur Info: Wie ich eine Anwendung mit Progressbar z.B. mit Backgroundworker ohne Einfrieren am Laufen halte, weiß ich, nur halt nicht mit einem modalen Dialog.
Gruß
Frank Moderiert von Kha: Topic aus WinForms verschoben am Sa 12.03.2011 um 13:18
|
|
Th69
      

Beiträge: 4796
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Sa 12.03.11 10:29
Hallo,
ein modales Fenster ist dann aber der falsche Weg, denn die aufrufende Form arbeitet erst weiter, wenn das Fenster wieder geschlossen wird (denn den Code zum Verändern der ProgressBar hast du doch in der Hauptform, oder?).
Der Ansatz mit dem Backgroundworker ist genau richtig.
Was genau willst du denn programmieren?
|
|
Oppi35 
      
Beiträge: 95
Erhaltene Danke: 3
|
Verfasst: Sa 12.03.11 13:34
Hallo Th69,
vielen Dank für Deine Hilfe.
Richtig, der Code ist in der Hauptform. Grundgedanke war, dass sich bei einer längeren Rechenarbeit die Progressbar in einem neuen Fenster öffnet und während der Berechnung auch im Vordergrund verweilt. Das Hauptfenster soll in dieser Zeit auch gesperrt werden. Das ist doch in vielen Anwendungen so. Allerdings weiß ich nicht, ob dies über modale Dialogfenster gesteuert wird. Lt. Deiner Mail scheinbar nicht.
Also müsste ich dann in WPF z.B. die TopMost Property auf True setzen und das Hauptformular ggfs. für Eingaben während der Berechnung manuell mit Code sperren?! Ich bin davon ausgegangen, ich könnte mir dies mit einem Modalen Dialog etwas vereinfachen:)
Gruß
Frank
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Sa 12.03.11 13:46
Ich glaube eher, Th69 hat dich missverstanden; jedenfalls sollte es der ProgressBar ziemlich egal sein, ob sie nun auf einem modalen oder nichtmodalen Fenster sitzt  . Ohne Code und eine genauere Beschreibung als "klappt nicht" kommen wir also wahrscheinlich nicht weiter.
/Edit: Vielleicht die wichtigste Frage: Wo und wie wird das Update der ProgressBar ausgelöst?
_________________ >λ=
|
|
Th69
      

Beiträge: 4796
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Sa 12.03.11 13:55
Hallo zusammen,
nein, ich habe es nicht mißverstanden.
Nur warum postet du (Oppi35) im WinForms-Forum, wenn du jetzt von WPF schreibst.
Generell gilt aber für beide: einfach die Enabled (bzw. IsEnabled) - Eigenschaft der Hauptform während der Berechnung (und Aktualisierung der ProgressBar) im BackgroundWorker deaktivieren (false) und nach getaner Arbeit (im BackgroundWorker.RunWorkerCompleted-Ereignis) wieder aktivieren (true).
Aber wie schon geschrieben, die ProgressBar-Form nur mittels Show() aufrufen (bzw. besser sogar mittels Show(this), damit das Hauptform als Owner dem SubForm übergeben wird - dann brauchst du auch nicht TopMost zu setzen)!
Für diesen Beitrag haben gedankt: Oppi35
|
|
Oppi35 
      
Beiträge: 95
Erhaltene Danke: 3
|
Verfasst: Sa 12.03.11 14:23
Hallo Zusammen,
Th69:
Es ging nicht speziell um Windows Forms. Mir ging es um die grundsätzliche Vorgehensweise. Mit Deinem letzten Posting ist die Sache für mich jetzt absolut einleuchtend. Werde jetzt genau so vorgehen. Vielen Dank für Deine Hilfe.
Kha:
Auch Dir vielen Dank für die Hilfe.
Es reicht 2 Forms zu erstellen (Form1 und Form2). In Form2 existiert eine Progressbar (progressbar1).
In Form1 ruft man folg. Code auf:
C#-Quelltext 1: 2: 3:
| Form2 form2=new Form2; form2.ShowDialog(); form2.progessbar1.Value=50; |
Ergebnis:
Die Progressbar wird nicht auf 50 gesetzt, da der Code erst weiter läuft, wenn der Dialog geschlossen wird.
Ich habe vor meinem Posting auch alles durch-gegoogeled. Die Frage gab es häufiger, aber keiner der abgedruckten Codes hat wirklich funktioniert. Ich gehe davon aus, dass der Zugriff auf ein modales Fenster während ShowDialog() nicht möglich ist.
Die Ausführungen von Th69 reichen mir. Solltest Du allerdings einen Weg finden, wie man doch ein modales Fenster "manipulieren" kann, würde mich dies interessieren.
Also nochmal vielen Dank Euch Beiden.
Gruß
Frank
Moderiert von Christian S.: C#-Tags hinzugefügt
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Sa 12.03.11 14:32
|
|
Oppi35 
      
Beiträge: 95
Erhaltene Danke: 3
|
Verfasst: Sa 12.03.11 15:13
Hallo Kha,
dann ist hier jetzt doch mein Code:) Meines Erachtens geht es nicht.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158:
| using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Forms; using System.IO; using System.Diagnostics; using System.ComponentModel; using System.Threading;
namespace WpfApplication6 { delegate void CopyDelegate(); delegate void UpdateProgressDelegate(int prozent); public partial class MainWindow : Window { private FolderBrowserDialog folderBrowserDialog; private List<string> files; private Fortschrittsbalken fortschrittsbalken; private BackgroundWorker backgroundWorker; private UpdateProgressDelegate updateprogressdel; private Thread theThread; public MainWindow() { InitializeComponent(); lbl_Quellordner.Content = ""; lbl_Zielordner.Content = ""; folderBrowserDialog = new FolderBrowserDialog(); files = new List<string>(); updateprogressdel = new UpdateProgressDelegate(updateProgress); backgroundWorker = new BackgroundWorker(); backgroundWorker.WorkerReportsProgress = true; backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork); backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted); backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged); UpdateUI(); } private void updateProgress(int prozent) { fortschrittsbalken.processvalue = prozent; } void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { Debug.WriteLine("Prozent: " + e.ProgressPercentage.ToString()); fortschrittsbalken.processvalue = e.ProgressPercentage; System.Windows.Forms.Application.DoEvents(); }
void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { fortschrittsbalken.Close(); this.IsEnabled = true; this.Visibility = Visibility.Visible; }
void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { int counter = 0; foreach (string str in files) { backgroundWorker.ReportProgress(counter); counter++; } }
private void btn_Quellordner_Click(object sender, RoutedEventArgs e) { if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { cmb_Extension.Items.Clear(); lbl_Quellordner.Content = folderBrowserDialog.SelectedPath; foreach (string str in Directory.GetFiles(folderBrowserDialog.SelectedPath)) { if (!cmb_Extension.Items.Contains(System.IO.Path.GetExtension(str))) { cmb_Extension.Items.Add(System.IO.Path.GetExtension(str)); } } UpdateUI(); } }
private void btn_Zielordner_Click(object sender, RoutedEventArgs e) { if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) { lbl_Zielordner.Content = folderBrowserDialog.SelectedPath; UpdateUI();
} } private void button1_Click(object sender, RoutedEventArgs e) { lbl_Quellordner.Content = ""; lbl_Zielordner.Content = ""; cmb_Extension.Items.Clear(); files.Clear(); UpdateUI(); }
private void UpdateUI() { if (lbl_Quellordner.Content.ToString() != "" && lbl_Zielordner.Content.ToString()!="") { btn_Start.IsEnabled = true; } else { btn_Start.IsEnabled = false; } }
private void btn_Start_Click(object sender, RoutedEventArgs e) { files.Clear(); foreach (string str in Directory.GetFiles(lbl_Quellordner.Content.ToString())) { if (cmb_Extension.SelectedItem.ToString()==System.IO.Path.GetExtension(str)) { files.Add(str); } } this.IsEnabled = false; fortschrittsbalken = new Fortschrittsbalken(); fortschrittsbalken.progressBar1.Minimum = 0; fortschrittsbalken.progressBar1.Maximum = files.Count - 1; fortschrittsbalken.progressBar1.Value = 0; backgroundWorker.RunWorkerAsync(); fortschrittsbalken.ShowDialog(); } } } |
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: Sa 12.03.11 17:07
Habe deinen Code wie folgt vereinfacht, ProgressBar läuft einwandfrei durch  :
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57:
| public partial class MainWindow : Window { private List<string> files; private Fortschrittsbalken fortschrittsbalken; private BackgroundWorker backgroundWorker;
public MainWindow() { InitializeComponent(); files = new List<string>();
backgroundWorker = new BackgroundWorker(); backgroundWorker.WorkerReportsProgress = true; backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork); backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted); backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
}
void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { fortschrittsbalken.progressBar1.Value = e.ProgressPercentage; }
void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { fortschrittsbalken.Close(); }
void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { int counter = 0; foreach (string str in files) { backgroundWorker.ReportProgress(counter); Thread.Sleep(1000); counter++; } }
private void btn_Start_Click(object sender, RoutedEventArgs e) { files.Clear(); foreach (string str in Directory.GetFiles(@"C:\")) { files.Add(str); } fortschrittsbalken = new Fortschrittsbalken(); fortschrittsbalken.progressBar1.Minimum = 0; fortschrittsbalken.progressBar1.Maximum = files.Count - 1; fortschrittsbalken.progressBar1.Value = 0; backgroundWorker.RunWorkerAsync();
fortschrittsbalken.ShowDialog(); } } |
Meine Behauptung, dass der BackgroundWorker in der modalen Form ausgeführt werden müsse, ist natürlich Unsinn, da er nicht an eine Form, sondern an den SynchronizationContext gebunden ist. Trotzdem ist es immer ratsam, eine starke Kupplung von Forms (und natürlich ganz allgemein) zu vermeiden  .
_________________ >λ=
Für diesen Beitrag haben gedankt: Oppi35
|
|
|