c# - 进度条MVVM?

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

任何帮助将非常感激。

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

最佳答案

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

要解决您的问题,您应该将 View 模型分配给 DataContext您的MainWindow :

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

但是,如果您打算使用不同的 DataContext对于你的窗口,你可以绑定(bind)DataContextProgressBar :
<ProgressBar
    DataContext="{Binding Path=PsVm,
                          RelativeSource={RelativeSource AncestorType=local:MainWindow}}"
    (...) />

您还可以通过添加 PsVm. 来修改特定的绑定(bind)。为 Path 的值并使用 RelativeSource ,例如:
 Value="{Binding Path=PsVm.Progress,
                 RelativeSource={RelativeSource AncestorType=local:MainWindow},
                 Mode=OneWay}"

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

附带说明一下,您可能还想更改报告进度的方式 - 请注意 OnPropertyChanged在您的 DoWork方法是不是 从 UI 线程调用。正确的方法是:
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
    }
}

此外,为了支持进度报告,您应该设置 WorkerReportsProgresstrue在你的 worker 身上,例如:
var worker = new BackgroundWorker { WorkerReportsProgress = true };

关于c# - 进度条MVVM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44995875/

相关文章:

c# - IIS6 ASP.NET 2.0 应用程序缓存 - 大量数据的数据存储选项和性能

c# - 如何从 C# 中的 dll 导入访问 char***

javascript - 使用 CefSharp 将字符串/JSON 从 C# 传递到 JS

Silverlights Dataform 与 MVVM 和 WCF Ria 服务

c# - Mvvm Light 和 Visual C# Express?

c# - 如何连接到已经打开的浏览器?

c# - HitTest WPF 3D 模型部件

c# - 日期输入格式

c# - View 不会被模型更新

WPF/Silverlight : How to DataTrigger a Storyboard Animation in MVVM?