【问题标题】:Separate View not updating from background worker Mvvm不从后台工作人员 Mvvm 更新的单独视图
【发布时间】:2012-04-19 16:29:29
【问题描述】:

我在从另一个类中的后台工作人员更新单独打开的窗口的进度条时遇到问题。

程序执行如下:

  1. MainWindow 加载
  2. 单击按钮做一些工作并打开一个弹出窗口 进度条(新打开的窗口)
  3. 后台工作人员确实工作 并将进度报告到弹出进度条
  4. 弹出进度条 希望更新。

进度条值绑定到一个属性,在逐步调试器中,后台工作人员似乎正在更新该属性。这些更改不会反映在弹出进度条视图上。但是,绑定没有损坏,因为如果我手动尝试设置进度条的属性值,它可以正常工作。

此外,当我将进度条放在最初启动的 MainWindow 视图中时,它会更新得很好。有什么建议吗??

这里是一些代码:

MainWindowViewModel

public class MainWindowViewModel: BaseViewModel
{

    private void PerformSomeAction()
    {
        var popUpProgressBar = new PopUpProgressBarViewModel();
        popUpProgressBar.Show(popUpProgressBar);

        var worker = new BackgroundWorker { WorkerReportsProgress = true };

        worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args)
        {
            if (args.ProgressPercentage != popUpProgressBar.Progresser)
            {
                Progresser = args.ProgressPercentage;
                popUpProgressBar.Progresser = args.ProgressPercentage;
            }
        };

        worker.DoWork += delegate
        {


            for (int i = 0; i < 101; i++)
            {
                worker.ReportProgress(i);
                System.Threading.Thread.Sleep(10);
            }


            MessageBox.Show("Done");
        };

            worker.RunWorkerAsync();

    }


    private int _progresser;
    public int Progresser
    {
        get { return _progresser; }
        set
        {
            if (_progresser == value) return;
            _progresser = value;
            OnPropertyChanged("Progresser");
        }
    }

    private RelayCommand _startProcessing; //set private member
    public ICommand StartProcessing //public field used by xaml binding
    {
        get
        {
            return _startProcessing = MakeCommandSafely(_startProcessing, () => PerformSomeAction());
        }
    }
}

PopUpProgressBarViewModel

public class PopUpProgressBarViewModel : BaseViewModel
{
    private PopUpProgressBar _popUpProgressBar;

    public void Show(PopUpProgressBarViewModel context)
    {
        _popUpProgressBar = new PopUpProgressBar {DataContext = context};
        _popUpProgressBar.Show();
    }

    private int _progresser;
    public int Progresser
    {
        get { return _progresser; }
        set
        {
            if (_progresser == value) return;
            _progresser = value;
            OnPropertyChanged("Progresser");
        }
    }
}

对于完整的解决方案文件(这样你就可以看到发生了什么),see here

【问题讨论】:

    标签: c# mvvm


    【解决方案1】:

    正如@Doug 所说,因为您已经在设置 ​​DataContext:

     _popUpProgressBar = new PopUpProgressBar {DataContext = context};
    

    您可以将 PopUpProgressBar 更改为

     <Window x:Class="OpeningWindow_With_ProgressBar.View.PopUpProgressBar"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ViewModel="clr-namespace:OpeningWindow_With_ProgressBar.ViewModel" Title="PopUpProgressBar" Height="150" Width="300">
    
    <Grid>
    
        <StackPanel>
            <Label FontWeight="Bold">Loading Something</Label>
            <ProgressBar Minimum="0" Maximum="100" Margin="0,10,0,0" Height="25px" Width="250px" Value="{Binding Path=Progresser, Mode=OneWay}"></ProgressBar>
            <TextBlock Margin="10,10,0,0" Text="Details of loading..."></TextBlock>
        </StackPanel>
    
    </Grid>
    

    【讨论】:

    • 哈哈该死的,就这一行。谢谢大家:)
    【解决方案2】:

    您正在创建两个 PopUpProgressBarViewModel。您有一个在 PopUpProgressBar.xaml 中被创建为资源,而另一个正在 MainWindowViewModel 中创建(第 18 行)。

    您的 XAML 绑定到在 PopUpProgressBar.xaml 中创建的那个,而您要更新的那个是在 MainWindowViewModel 中创建的。

    如果你可以减少它,只创建一个,那应该可以解决你的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-27
      相关资源
      最近更新 更多