简体   繁体   English

如何使用MVVM手动增加/减少WPF进度栏

[英]How to manually increment/decrement a WPF progress bar using MVVM

I have searched in Google using a progress bar in WPF that will be manually incremented and decremented using a plus and minus button. 我已经在WPF中使用进度条在Google中进行了搜索,该进度条将使用加号和减号按钮进行手动递增和递减。 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. 如何实现将以MVVM方式手动增加或减少(使用按钮)的WPF进度条。 The screen capture below shows the mock-up UI design. 下面的屏幕截图显示了模拟UI设计。

在此处输入图片说明

The image show that when the user click the plus button, the progress bar will be incremented by 10 minutes. 该图显示,当用户单击加号按钮时,进度条将增加10分钟。 On the other hand, the minus button when clicked, decrements the progress bar by 10 minutes. 另一方面,单击减号按钮会使进度条减少10分钟。

I'm just starting to learn WPF and MVVM. 我才刚刚开始学习WPF和MVVM。 Any help is greatly appreciated. 任何帮助是极大的赞赏。

I created a simple example which uses WPF and MVVM to show how one model can be displayed with different views. 我创建了一个简单的示例,该示例使用WPF和MVVM演示如何使用不同的视图显示一个模型。 Here in xaml I placed on a form Slider and ProgressBar - they are Views for our ViewModel. 在xaml中,我将其放在一个SliderProgressBar窗体上-它们是我们ViewModel的视图。 The properties we need (Minimum, Maximum, Value) are binded to the ViewModel's properties. 我们需要的属性(最小,最大值,值)已绑定到ViewModel的属性。 "Plus" and "Minus" buttons' properties "Command" are also binded to the corresponding props in the ViewModel(IncreaseCommand, DecreaseCommand). “加号”和“减号”按钮的属性“命令”也绑定到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: 为了在ViewModel中实现命令功能,您将需要创建ICommand接口的实现:

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. 这是ViewModel类,它实现INotifyPropertyChanged接口以保持视图更新。

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: 最后使它正常工作的是创建新的ViewModel并将窗口的DataContext设置为此模型:

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

I think you should solve that by use custom Slider control of WPF instead Progress bar. 我认为您应该通过使用WPF的自定义Slider控件代替进度条来解决该问题。 This link can help you : http://www.codescratcher.com/wpf/custom-slider-control-in-wpf/ 该链接可以为您提供帮助: http : //www.codescratcher.com/wpf/custom-slider-control-in-wpf/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM