How to manually increment/decrement a WPF progress

2019-09-13 01:37发布

I have searched in Google using a progress bar in WPF that will be manually incremented and decremented using a plus and minus button. But, to no avail haven't found one that is similar to what I want though.

How do I implement a WPF progress bar that will be manually incremented or decremented (using buttons) in an MVVM way. The screen capture below shows the mock-up UI design.

enter image description here

The image show that when the user click the plus button, the progress bar will be incremented by 10 minutes. On the other hand, the minus button when clicked, decrements the progress bar by 10 minutes.

I'm just starting to learn WPF and MVVM. Any help is greatly appreciated.

标签: c# wpf mvvm
2条回答
【Aperson】
2楼-- · 2019-09-13 01:55

I think you should solve that by use custom Slider control of WPF instead Progress bar. This link can help you : http://www.codescratcher.com/wpf/custom-slider-control-in-wpf/

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-09-13 02:00

I created a simple example which uses WPF and MVVM to show how one model can be displayed with different views. Here in xaml I placed on a form Slider and ProgressBar - they are Views for our ViewModel. The properties we need (Minimum, Maximum, Value) are binded to the ViewModel's properties. "Plus" and "Minus" buttons' properties "Command" are also binded to the corresponding props in the ViewModel(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>

For implementing the commands functionality in ViewModel you will need to create an implementation of ICommand interface:

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);
    }
}

And here's the ViewModel class, it implements INotifyPropertyChanged interface to keep views updated.

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);
    }
}

And the last thing to get it all working is to create new ViewModel and set DataContext of a window to this model:

public MainWindow()
{
    InitializeComponent();
    var model = new ViewModel();
    DataContext = model;
}
查看更多
登录 后发表回答