Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 进度条MVVM?_C#_Wpf_Mvvm - Fatal编程技术网

C# 进度条MVVM?

C# 进度条MVVM?,c#,wpf,mvvm,C#,Wpf,Mvvm,我在使用ProgressBar时遇到了一点麻烦。当我启动它时,什么也没发生,我不明白为什么 我认为这将启动任务worker.RunWorkerAsync() 下面的示例应该能够复制并粘贴到新的解决方案中,并在需要时运行以进行测试 XAML <Grid Margin="20"> <ProgressBar Height="60" Minimum="0" Maximum="100" Value="{Bindi

我在使用
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));
        }
    }
}
公共部分类主窗口:窗口
{
公共程序BarViewModel PsVm{get;set;}
公共主窗口()
{
初始化组件();
PsVm=新的ProggressbarViewModel();
}
公共类ProggersBarViewModel
{
公共项目BarViewModel()
{
var worker=新的BackgroundWorker();
worker.DoWork+=DoWork;
worker.ProgressChanged+=ProgressChanged;
worker.RunWorkerAsync();
}
私人互联网进展;
公共信息技术进步
{
获取{return\u progress;}
设置
{
if(_progress==value)返回;
_进步=价值;
OnPropertyChanged();
}
}
私有无效DoWork(对象发送方,DoWorkEventArgs e)
{
对于(int i=0;i<100;i++)
{
睡眠(100);
_进展=i;
OnPropertyChanged();
}
}
私有void ProgressChanged(对象发送方,progresschangedventargs e)
{
进度=e.ProgressPercentage;
}
公共事件属性更改事件处理程序属性更改;
public void OnPropertyChanged([CallerMemberName]字符串propertyName=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
任何帮助都将不胜感激


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

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

要解决问题,您应该将视图模型指定给
主窗口的
数据上下文

public MainWindow()
{
    InitializeComponent();
    PsVm = new ProggressbarViewModel();
    DataContext = PsVm;
}
但是,如果您计划对窗口使用不同的
DataContext
,则可以绑定
ProgressBar的
DataContext

<ProgressBar
    DataContext="{Binding Path=PsVm,
                          RelativeSource={RelativeSource AncestorType=local:MainWindow}}"
    (...) />
但是,在这种情况下,您必须修改每个绑定,因此以前的解决方案更快和/或更简单

作为补充说明,您可能还希望更改报告进度的方式—请注意,
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
    }
}

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

要解决问题,您应该将视图模型指定给
主窗口的
数据上下文

public MainWindow()
{
    InitializeComponent();
    PsVm = new ProggressbarViewModel();
    DataContext = PsVm;
}
但是,如果您计划对窗口使用不同的
DataContext
,则可以绑定
ProgressBar的
DataContext

<ProgressBar
    DataContext="{Binding Path=PsVm,
                          RelativeSource={RelativeSource AncestorType=local:MainWindow}}"
    (...) />
但是,在这种情况下,您必须修改每个绑定,因此以前的解决方案更快和/或更简单

作为补充说明,您可能还希望更改报告进度的方式—请注意,
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
    }
}

可能是@Clint的副本,是的,我看到了那个线程。这对我没有多大帮助,因为我不知道我会错在哪里。可能是@Clint的副本,是的,我看到了那个线程。这对我没有多大帮助,因为我不知道哪里出了问题。我将把它标记为已解决和UV,因为代码中的所有内容都在工作。我似乎有数据上下文问题需要解决。谢谢Grx70,多亏了您的帮助,我才得以工作。DataContext问题已经解决。干杯。我将把这个标记为已解决和UV,因为代码中的所有内容都在工作。我似乎有数据上下文问题需要解决。谢谢Grx70,多亏了您的帮助,我才得以工作。DataContext问题已经解决。干杯