2017-07-09 4 views
0

Ich habe ein bisschen Mühe, eine ProgressBar zu arbeiten. Wenn ich anfange, passiert nichts und ich kann nicht sehen warum?Fortschrittsbalken MVVM?

Ich dachte, dass dies die Aufgabe worker.RunWorkerAsync();

Das folgende Beispiel und in eine neue Lösung eingefügt werden soll kopiert werden kann beginnen würde und für die Prüfung durchgeführt werden, wenn nötig.

Die XAML,

<Grid Margin="20"> 
    <ProgressBar 
     Height="60" 
     Minimum="0" 
     Maximum="100" 
     Value="{Binding Progress, Mode=OneWay}" 
     Visibility="{Binding ProgressVisibility}"/> 
</Grid> 

Mein Code,

public partial class MainWindow : Window 
{ 
    public ProggressbarViewModel PsVm { get; set; } 

    public MainWindow() 
    { 
     InitializeComponent(); 
     PsVm = new ProggressbarViewModel(); 
    } 

    public class ProggressbarViewModel 
    { 
     public ProggressbarViewModel() 
     { 
      var worker = new BackgroundWorker(); 
      worker.DoWork += DoWork; 
      worker.ProgressChanged += ProgressChanged; 
      worker.RunWorkerAsync(); 
     } 

     private int _progress; 

     public int Progress 
     { 
      get { return _progress; } 
      set 
      { 
       if (_progress == value) return; 
       _progress = value; 
       OnPropertyChanged(); 
      } 
     } 

     private void DoWork(object sender, DoWorkEventArgs e) 
     { 
      for (int i = 0; i < 100; i++) 
      { 
       Thread.Sleep(100); 
       _progress = i; 
       OnPropertyChanged(); 
      } 
     } 

     private void ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      Progress = e.ProgressPercentage; 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     public void OnPropertyChanged([CallerMemberName] string propertyName = null) 
     { 
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

Jede Hilfe sehr geschätzt würde.

EDIT: Die Frage ist ähnlich ist möglicherweise ein Duplikat in diesem Sinne, aber die verknüpfte Antwort löste mein Problem nicht, wie es im Duplicate-Banner angibt.

+0

Mögliche Duplikat von [Wie implementieren ein Fortschrittsbalken mit dem MVVM-Muster] (https://stackoverflow.com/questions/3520359/how-to-implement-a-progress-bar-using-the-mvvm-pattern) – Clint

+0

@ Clint, ja, ich sah diesen Thread . Hilft mir nicht viel, da ich nicht weiß, wo ich falsch liege. – KyloRen

Antwort

3

Wenn Sie nicht explizit sind angibt Quellobjekt für Ihre Bindungen (mittels Binding.Source oder Binding.RelativeSource Eigenschaften), der Rahmen verwendet (geerbt möglicherweise) Wert von DataContext des Zielobjekts als Quelle. Das Problem besteht darin, dass Sie Ihr Ansichtsmodell nicht der Eigenschaft DataContext eines beliebigen Steuerelements zuweisen. Daher wird die Quelle für die Bindungen auf null aufgelöst und auf Ihrer Fortschrittsleiste wird nichts angezeigt.

Um Ihr Problem zu beheben Sie die Ansicht Modell auf die DataContext Ihrer MainWindow zuweisen sollte:

public MainWindow() 
{ 
    InitializeComponent(); 
    PsVm = new ProggressbarViewModel(); 
    DataContext = PsVm; 
} 

Wenn aber Sie planen, über die Verwendung verschiedener DataContext für Ihre Fenster können Sie DataContext von ProgressBar binden:

<ProgressBar 
    DataContext="{Binding Path=PsVm, 
          RelativeSource={RelativeSource AncestorType=local:MainWindow}}" 
    (...) /> 

Sie könnten auch bestimmte Bindungen ändern, indem PsVm. auf den Wert von Path vorangestellt und mit RelativeSource, z.B .:

Value="{Binding Path=PsVm.Progress, 
       RelativeSource={RelativeSource AncestorType=local:MainWindow}, 
       Mode=OneWay}" 

In diesem Fall jedoch würden Sie jede Bindung ändern müssen, so bisherige Lösungen sind schneller und/oder einfacher.

Als Randbemerkung, mögen Sie vielleicht auch die Art und Weise ändern, die Sie Fortschritte sind Berichterstattung - beachten Sie, dass OnPropertyChanged in Ihrer DoWork Methode ist nicht von UI-Thread aufgerufen. Der richtige Weg, es zu tun wäre:

private void DoWork(object sender, DoWorkEventArgs e) 
{ 
    var worker = (BackgroundWorker)sender; 
    for (int i = 0; i < 100; i++) 
    { 
     Thread.Sleep(100); 
     worker.ReportProgress(i); //This will raise BackgroundWorker.ProgressChanged 
    } 
} 

Auch, um Berichterstattung über die Fortschritte zu unterstützen, Sie WorkerReportsProgress zu true auf Ihrem Arbeiter-Set soll, zB:

var worker = new BackgroundWorker { WorkerReportsProgress = true }; 
+0

Ich werde dies als gelöst und UV markieren, wegen allem, was im Code funktioniert. Es scheint, ich habe Data-Kontext Problem muss ich aussortieren. – KyloRen

+0

Danke Grx70, ich habe es funktioniert dank Ihrer Hilfe. Das DataContext-Problem wurde behoben. Prost. – KyloRen