簡體   English   中英

在WPF中的另一個窗口上更新屬性的值

[英]Update property's value on another Window in WPF

我的ViewModel中有一個屬性,其值在BackgroundWorker的DoWork方法中已更改。 當我啟動應用程序並單擊啟動BackgroundWorker的按鈕時,我會看到此屬性的值如何變化。 但是,當我打開新窗口時,即使BackgroundWorker仍在運行,此屬性仍保留其默認值,並且不會更新。

她是我的ViewModel中的代碼:

private string currentData;

...

public ViewModel()
    {
        ...

        // Property initialised with a default value
        currentData = "BackgroundWorker is not running";

        ...
    }

public string CurrentData
    {
        get { return this.currentData; }
        private set
        {
            if (this.currentData != value)
            {
                this.currentData = value;
                this.RaisePropertyChanged("CurrentData");
            }
        }
    }

private void DoWork(object sender, DoWorkEventArgs e)
    {
        isUpdating = true;

        ...

        this.CurrentData = "BackgroundWorker is running...";

        for (...)
        {
            ...

            if(...)
            {
                this.CurrentData = "value1";
            }

            else
            {
                this.CurrentData = "value2";

                ...
            }     
        }
    }

RaisePropertyChanged方法:

private void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

兩個窗口(MainWindow和newtWindow)的XAML代碼:

<TextBlock Margin="10" MinWidth="250" VerticalAlignment="Center" Text="{Binding CurrentData}" FontSize="12" Foreground="White" HorizontalAlignment="Left" />

BackgroundWorker:

private readonly BackgroundWorker worker;

...

public ImageViewModel()
    {
        currentData = "BackgroundWorker is not running";

        this.worker = new BackgroundWorker();
        this.worker.DoWork += this.DoWork;
        this.worker.ProgressChanged += this.ProgressChanged;
        this.worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_Completeted);
        this.worker.WorkerReportsProgress = true;
    }

您能告訴我我做錯了什么以及如何解決嗎?

您必須在屬性之外創建一個私有字符串引用,該屬性可以在其中設置值並將其保存在堆棧中,就像這樣(這是wpf如何從text屬性中的文本框中獲取信息)

     private string _text;   //string that is used as a reference which you can plug your new new window

    public string Text
    {
        get
        {
            return this._text;
        }
        set
        {
            this._text = value;
            if (null != PropertyChanged)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs  ("Text"));
            }
        }
    }

我會避免從后台線程更新綁定到UI的屬性。 我不確定這是否可以解決您的問題,但是我會嘗試使用BackgroundWorker的ReportProgress方法將有關CurrentData的更改通知給ViewModel。 然后,可以在OnProgressChanged事件處理程序中將CurrentData設置為新的String。

public void ReportProgress(int percentProgress, object userState)

您可以將String放入“ userState”對象。

編輯

像這樣的東西:

public ViewModel()
    {
        ...

        backgroundWorker.ReportsProgress = true;
        backgroundWorker.ProgressChanged += OnProgressChanged;

        ...
    }

private void DoWork(object sender, DoWorkEventArgs e)
{
    isUpdating = true;

    ...

    ReportProgress(0,"BackgroundWorker is running...");

    for (...)
    {
        ...

        if(...)
        {
            ReportProgress(0,"value1");
        }

        else
        {
            ReportProgress(0,"value2");

            ...
        }     
    }
}

private void OnProgressChanged(object sender, ProgressChangedEventArgs e)
{
    this.CurrentData = (string)e.UserState;
}

好的,到目前為止,我的理解是:

從您最初的問題:

但是,當我打開新窗口時,即使BackgroundWorker仍在運行,此屬性仍保留其默認值,並且不會更新。

從您的評論到我以前關於設置窗口的DataContext的答案:

<Window.DataContext> <local:ViewModel /> </Window.DataContext>

創建新窗口時,還將創建ViewModel的新實例。 這個新實例也有自己的BackgroundWorker。 當您說“ ...即使BackgroundWorker仍在運行”時,這僅適用於您的第一個窗口,因為必須首先啟動新窗口中的Backgroundworker。

如果兩個窗口都需要相同的DataContext(因此需要相同的BackgroundWorker),則需要將新窗口的DataContext設置為ViewModel的現有實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM