3

別のクラス内のバックグラウンド ワーカーから個別に開いたウィンドウのプログレス バーを更新する際に問題が発生しています。

プログラムの実行は次のようになります。

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

完全なソリューション ファイル (何が起こっているかを確認できるようにするため)については、こちらを参照してください。

4

2 に答える 2

0

2 つの PopUpProgressBarViewModel を作成しています。1 つは PopUpProgressBar.xaml 内のリソースとして作成され、もう 1 つは MainWindowViewModel で作成されています (18 行目)。

XAML は PopUpProgressBar.xaml 内で作成されたものにバインドされていますが、更新しているものは MainWindowViewModel で作成されたものです。

1つだけが作成されるように削減できれば、問題は解決するはずです。

于 2012-04-19T16:47:19.373 に答える
0

@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>

于 2012-04-19T17:02:44.000 に答える