2016-12-22 1 views
0

Ich habe in Google mit einem Fortschrittsbalken in WPF gesucht, der manuell mit einer Plus- und Minus-Schaltfläche inkrementiert und dekrementiert wird. Aber vergebens habe ich keins gefunden, das dem ähnlich ist, was ich möchte.Manuelles Erhöhen/Dekrementieren eines WPF-Fortschrittsbalkens mithilfe von MVVM

Wie implementiere ich einen WPF-Fortschrittsbalken, der auf MVVM-Basis manuell inkrementiert oder dekrementiert wird (mithilfe von Schaltflächen). Die Bildschirmaufnahme unten zeigt das Mock-Up-UI-Design.

enter image description here

Das Bild zeigt, dass, wenn der Benutzer die Plus-Schaltfläche klicken, wird der Fortschrittsbalken von 10 Minuten erhöht werden. Auf der anderen Seite verringert die Minus-Taste beim Anklicken den Fortschrittsbalken um 10 Minuten.

Ich fange gerade an, WPF und MVVM zu lernen. Jede Hilfe wird sehr geschätzt.

Antwort

1

Ich habe ein einfaches Beispiel erstellt, das WPF und MVVM verwendet, um zu zeigen, wie ein Modell mit verschiedenen Ansichten angezeigt werden kann. Hier in Xaml habe ich auf einem Formular Slider und ProgressBar platziert - sie sind Ansichten für unser ViewModel. Die Eigenschaften, die wir benötigen (Minimum, Maximum, Wert), werden an die Eigenschaften des ViewModels gebunden. Die "Plus" - und "Minus" -Buttons-Eigenschaften "Command" werden ebenfalls an die entsprechenden Requisiten im ViewModel gebunden (IncreaseCommand, DecreaseCommand).

<Window> 
    <StackPanel Orientation="Horizontal"> 
     <Button Width="50" Height="40" Content="-" Command="{Binding DecreaseCommand}"/> 
     <StackPanel Width="400" Orientation="Vertical"> 
      <Slider Height="40" Margin="0,50,0,0" Minimum="{Binding Minimum}" Maximum="{Binding Maximum}" Value="{Binding Value}"/> 
      <ProgressBar Height="40" Margin="0,100,0,0" Minimum="{Binding Minimum}" Maximum="{Binding Maximum}" Value="{Binding Value}"/> 
      <TextBlock TextAlignment="Center" Margin="0,50,0,0" Text="{Binding Value}"/> 
     </StackPanel> 
     <Button Width="50" Height="40" Content="+" Command="{Binding IncreaseCommand}"/> 
    </StackPanel> 
</Window> 

Für die Befehle Funktionalität in Ansichtsmodell Implementierung benötigen Sie eine Implementierung von ICommand Schnittstelle zu erstellen:

public class RelayCommand : ICommand 
{ 
    private Predicate<object> _canExecute; 
    private Action<object> _execute; 

    public RelayCommand(Predicate<object> canExecute, Action<object> execute) 
    { 
     _canExecute = canExecute; 
     _execute = execute; 
    } 

    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 

    public bool CanExecute(object parameter) 
    { 
     return _canExecute(parameter); 
    } 

    public void Execute(object parameter) 
    { 
     _execute(parameter); 
    } 
} 

Und hier ist der Viewmodel Klasse, implementiert es INotifyPropertyChanged Schnittstelle Ansichten zu halten aktualisiert.

public class ViewModel:INotifyPropertyChanged 
{ 
    public ViewModel() 
    { 
     _value = 0; 
     _minimum = 0; 
     _maximum = 180; 
     _step = 10; 
    } 

    private int _step; 
    private int _minimum; 
    private int _maximum; 

    private ICommand _increaseCommand; 
    public ICommand IncreaseCommand 
    { 
     get 
     { 
      if (_increaseCommand == null) 
      { 
       _increaseCommand = new RelayCommand(
       p => _value + _step <= _maximum, 
       Increase); 
      } 
      return _increaseCommand; 
     } 
    } 

    private ICommand _decreaseCommand; 
    public ICommand DecreaseCommand 
    { 
     get 
     { 
      if (_decreaseCommand == null) 
      { 
       _decreaseCommand = new RelayCommand(
       p => _value - _step >= _minimum, 
       Decrease); 
      } 
      return _decreaseCommand; 
     } 
    } 


    private void Increase(object param) 
    { 
     Value = Value + _step; 
    } 

    private void Decrease(object param) 
    { 
     Value = Value - _step; 
    } 

    private int _value; 
    public int Value 
    { 
     get { return _value; } 
     set { _value = value; InvokePropertyChanged(new PropertyChangedEventArgs("Value")); } 
    } 

    public int Minimum 
    { 
     get { return _minimum; } 
    } 

    public int Maximum 
    { 
     get { return _maximum; } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void InvokePropertyChanged(PropertyChangedEventArgs e) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) handler(this, e); 
    } 
} 

Und das letzte, was zu bekommen es alle Arbeiten zu schaffen neues Ansichtsmodell und setzte DataContext ein Fenster zu diesem Modell:

public MainWindow() 
{ 
    InitializeComponent(); 
    var model = new ViewModel(); 
    DataContext = model; 
} 
+0

das ist genial. Ich schätze deine Hilfe sehr. Das Stück Code, das du geschrieben hast, funktioniert gut und die Bindung ist wirklich großartig. Dies ist ein guter Anfang für mich, wie man ICommand und INPC implementiert. Du hast meinen Tag gerettet. Ich danke dir sehr. – Juniuz

+0

@Juniuz Wenn Sie ein Anfänger in MVVM sind, empfehle ich Ihnen [Rachels Blog] (https://rachel53461.wordpress.com/2011/05/08/simplemvvmexample/), es hat mir viel geholfen, das Muster und die Implementierung von zu verstehen MVVM, als ich gerade angefangen habe, es zu lernen. – lena

+0

Ja, ich bin ein Neuling in MVVM. Danke für das Teilen des Blogs. Ich bin mir sicher, dass es mir sehr helfen wird, indem ich mehr MVVM-basierte Anwendungen schreiben werde. – Juniuz

0

Ich denke, Sie sollten das lösen, indem Sie benutzerdefinierte Slider-Steuerelement von WPF statt Fortschrittsbalken verwenden. Dieser Link kann Ihnen helfen: http://www.codescratcher.com/wpf/custom-slider-control-in-wpf/

+0

Dank für den Link zu teilen. Der Schieberegler ist im Vergleich zu einem Fortschrittsbalken sinnvoll. Ich habe das benutzerdefinierte Schieberegler-Steuerelement überprüft und es hat die Funktionalität, die ich in UI-Perspektive brauche. Es hat jedoch keine Implementierung, wie das Schieberegler und Schaltflächen (+ und -) mit MVVM zu binden? – Juniuz

+0

@Juniuz haben eine Eigenschaft in Model und binden diese an Slider's Value. Wenn Sie die Eigenschaft aktualisieren, wird der Wert aktualisiert (INotifyPropertyChanged muss) – WPFUser

+0

@WPFUser, vielen Dank für Ihren Vorschlag. – Juniuz

Verwandte Themen