我在获取 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.Source
或 Binding.RelativeSource
属性),框架使用(可能继承的)值 DataContext
目标对象作为源。问题是您没有将 View 模型分配给 DataContext
任何控件的属性。因此,绑定(bind)的源解析为 null
并且您的进度条上没有显示任何内容。
要解决您的问题,您应该将 View 模型分配给 DataContext
您的MainWindow
:
public MainWindow()
{
InitializeComponent();
PsVm = new ProggressbarViewModel();
DataContext = PsVm;
}
但是,如果您打算使用不同的
DataContext
对于你的窗口,你可以绑定(bind)DataContext
的 ProgressBar
:<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
}
}
此外,为了支持进度报告,您应该设置
WorkerReportsProgress
至true
在你的 worker 身上,例如:var worker = new BackgroundWorker { WorkerReportsProgress = true };
关于c# - 进度条MVVM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44995875/