Es ist mein erster Beitrag hier, also hoffe ich, dass ich alles richtig mache.Progressbar Fortschritt während langer Aufgabe
Ich verwende das .NET Framework 4-Clientprofil.
Ich möchte Daten aus einer DOC-Datei in mein Programm laden und mit diesen Informationen arbeiten. Dies kann viel Zeit in Anspruch nehmen, da ich die Tabellen des Dokuments durchgehen und prüfen muss, was sich darin befindet. Das funktioniert schon, das einzige Problem hier ist, dass der Bildschirm friert und man nicht sehen kann, ob etwas passiert.
Auch ich weiß, das wäre schneller und viel einfacher in Excel, aber da diese Art von Daten immer und in Word-Dokumente in unserer Firma gespeichert ist, muss ich es so halten.
Also, was ich tun möchte, ist es, alle Zeilen aus den Tabellen zählen, die ich gelesen habe, setzen Sie diese als mein Maximalwert für die Progress-Bar und dann nach jeder Zeile würde ich den Wert + 1
zähltich meine Last haben Button
mit dem Command
gebunden LoadWordDocCmd
und dem Fortschrittsbalken:
<Button Name="btnLoadFile"
Content="Load" Height="23"
Command="{Binding LoadWordDocCmd}"
HorizontalAlignment="Right" Margin="0,22,129,0"
VerticalAlignment="Top" Width="50"
Visibility="{Binding VisModeAddNew}"
/>
<ProgressBar HorizontalAlignment="Left" Height="24" Margin="574,52,0,0"
VerticalAlignment="Top" Width="306"
Name="prgBarAddNewLoadWord"
Minimum="0"
Maximum="{Binding AddNewProgressBarMaxVal, Mode=OneWay}"
Value="{Binding AddNewProgressBarValue, Mode=OneWay}"
Visibility="{Binding AddNewProgressBarVisible}"/>
Hier ist die RelayCommand
:
/// <summary>
/// Relaycommand for Function loadWordDocument
/// </summary>
public RelayCommand LoadWordDocCmd
{
get
{
if (this.m_loadWordDocCmd == null)
{
this.m_loadWordDocCmd = new RelayCommand(this.loadWordDocument, canLoadWordDoc);
}
return m_loadWordDocCmd;
}
private set
{
this.m_loadWordDocCmd = value;
}
}
/// <summary>
/// checks if the Word Document can be loaded
/// </summary>
/// <param name="parameter">not used</param>
/// <returns>if it could Execute, then true, else false</returns>
private bool canLoadWordDoc(object parameter)
{
bool ret = false;
if (this.m_fileSelected)
{
ret = true;
}
return ret;
}
Was ich schon getan habe, war mit einer BackgroundWorker
zu arbeiten. Ich konnte den Button-Befehl an eine Funktion binden, die eine RelayCommand
mit der BackgroundWorker
hat, aber dann konnte ich die canExecute-Funktion nicht mehr überprüfen.
benutzte ich diese die Progress-Bar zu testen, die Arbeit wurde:
XAML:
<Button ...
Command="{Binding Path=InstigateWorkCommand}"
/>
cs:
private BackgroundWorker worker;
private ICommand instigateWorkCommand;
public ProggressbarSampleViewModel()
{
this.instigateWorkCommand = new
RelayCommand(o => this.worker.RunWorkerAsync(), o => !this.worker.IsBusy);
this.worker = new BackgroundWorker();
this.worker.DoWork += this.DoWork;
this.worker.ProgressChanged += this.ProgressChanged;
}
public ICommand InstigateWorkCommand
{
get { return this.instigateWorkCommand; }
}
private int _currentProgress;
public int CurrentProgress
{
get { return this._currentProgress; }
private set
{
if (this._currentProgress != value)
{
this._currentProgress = value;
OnPropertyChanged("CurrentProgress");
}
}
}
private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.CurrentProgress = e.ProgressPercentage;
}
private void DoWork(object sender, DoWorkEventArgs e)
{
// do time-consuming work here, calling ReportProgress as and when you can
for (int i = 0; i < 100; i++)
{
Thread.Sleep(1000);
_currentProgress = i;
OnPropertyChanged("CurrentProgress");
}
}
Aber wie kann ich dies mit dem arbeiten kannausführen? Hier ist meine Funktion-Rubrik:
/// <summary>
/// Function for Load Word Document
/// </summary>
/// <param name="parameter">not used</param>
private void loadWordDocument(object parameter)
Hier ist die Relay-Command-Klasse:
public class RelayCommand : ICommand
{
private readonly Action<object> methodToExecute;
private readonly Func<object, bool> canExecute;
public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged()
{
EventHandler handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
public RelayCommand(Action<object> execute)
: this(execute, null) { }
public RelayCommand(Action<object> methodToExecute, Func<object, bool> canExecute)
{
this.methodToExecute = methodToExecute;
this.canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
// wird keine canExecute-Funktion übergeben, so liefert diese
// true zurück, ansonsten wird die custom canExecute-Funktion
// mit den übergebenen Parametern aufgerufen.
return canExecute == null ? true : canExecute.Invoke(parameter);
}
public void Execute(object parameter)
{
methodToExecute(parameter);
}
}
Vielen Dank für Ihre Hilfe und ich hoffe, dass ich gepostet diese Frage richtig!
Verwenden Sie Task und IProgress anstelle von BackgroundWorker eine Option für Sie? Siehe https://stackoverflow.com/a/35316334/982149 – Fildor
Sie sollten die RaiseCanExecuteChanged() - Methode des Befehls immer dann aufrufen, wenn Sie den Status der Schaltfläche aktualisieren möchten. Was funktioniert und was ist nicht ...? – mm8
Ich konnte nicht einmal den RelayCommand mit dem canExecuteChange arbeiten lassen. Bei Verwendung von RelayCommand (o => this.worker.RunWorkerAsync(), o =>! This.worker.IsBusy); Ich wusste nicht, wie man den Funktionszeiger für canLoadDoc zum Arbeiten bringt – kpischi