【问题标题】:Progress-bar MVVM?进度条MVVM?
【发布时间】:2017-07-09 11:26:01
【问题描述】:

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

任何帮助将不胜感激。

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

【问题讨论】:

标签: c# wpf mvvm


【解决方案1】:

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

要解决您的问题,您应该将您的视图模型分配给您的MainWindowDataContext

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

如果您打算为您的窗口使用不同的DataContext,您可以绑定DataContext of ProgressBar

<ProgressBar
    DataContext="{Binding Path=PsVm,
                          RelativeSource={RelativeSource AncestorType=local:MainWindow}}"
    (...) />

您还可以通过在 Path 的值前面加上 PsVm. 并使用 RelativeSource 来修改特定的绑定,例如:

 Value="{Binding Path=PsVm.Progress,
                 RelativeSource={RelativeSource AncestorType=local:MainWindow},
                 Mode=OneWay}"

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

附带说明,您可能还想更改报告进度的方式 - 请注意,您的 DoWork 方法中的 OnPropertyChanged不是从 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
    }
}

另外,为了支持进度报告,您应该在您的工作人员上将WorkerReportsProgress 设置为true,例如:

var worker = new BackgroundWorker { WorkerReportsProgress = true };

【讨论】:

  • 我将把它标记为已解决和 UV,因为代码中的所有内容都在工作。看来我有需要解决的数据上下文问题。
  • 感谢 Grx70,感谢您的帮助,我得到了它的帮助。解决了 DataContext 问题。干杯。
猜你喜欢
  • 2021-12-19
  • 2015-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多