进度条MVVM?

时间:2017-07-09 11:26:01

标签: c# wpf mvvm

ProgressBar工作时遇到一些麻烦。当我启动时,没有任何反应,我不明白为什么?

我认为这会启动任务worker.RunWorkerAsync();

以下示例应该能够复制并粘贴到新的解决方案中,并在需要时运行以进行测试。

XAML,

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

我的代码,

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

非常感谢任何帮助。

编辑:在这个意义上问题是类似的可能是重复的,但链接的答案并没有解决我的问题,就像它在复制横幅中所述。

1 个答案:

答案 0 :(得分:3)

当您没有明确指出绑定的源对象时(通过Binding.SourceBinding.RelativeSource属性),框架使用(可能是继承的)目标DataContext的值对象作为源。问题是您没有将视图模型分配给任何控件的DataContext属性。因此,绑定的源解析为null,并且您的进度条上没有显示任何内容。

要解决您的问题,您应该将视图模型分配到DataContext的{​​{1}}:

MainWindow

但是,如果您计划在窗口中使用不同的public MainWindow() { InitializeComponent(); PsVm = new ProggressbarViewModel(); DataContext = PsVm; } ,则可以约束DataContext DataContext

ProgressBar

您还可以通过将<ProgressBar DataContext="{Binding Path=PsVm, RelativeSource={RelativeSource AncestorType=local:MainWindow}}" (...) /> 添加到PsVm.的值并使用Path来修改特定的绑定,例如:

RelativeSource

在这种情况下,您必须修改每个绑定,因此以前的解决方案更快和/或更简单。

作为旁注,您可能还想更改报告进度的方式 - 请注意,您的 Value="{Binding Path=PsVm.Progress, RelativeSource={RelativeSource AncestorType=local:MainWindow}, Mode=OneWay}" 方法中的OnPropertyChanged 来自UI线程。正确的方法是:

DoWork

此外,为了支持进度报告,您应该在工作人员上设置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 } } WorkerReportsProgress,例如:

true
相关问题