簡體   English   中英

從另一個項目中的方法設置 ViewModel 屬性

[英]Setting ViewModel Property from Method in Another Project

初學者 - 我正在努力解決訪問視圖模型屬性的問題。 在我的特殊情況下,我有一個包含兩個不同項目的解決方案。 一個包含 UI 組件,另一個包含大部分“工作”。

我的 UI 項目中的視圖模型包含以下屬性:

   private int _createfileprogress { get; set; }

   public int CreateFileProgress
    {
        get { return _createfileprogress ; }
        set
        {
            if (value == _createfileprogress )
                return;

            _createfileprogress = value;
            OnPropertyChanged("CreateFileProgress");
        }
    }

這個 int 屬性的目的是填充進度條的進度。 我想在我的另一個項目中引用它,其中一個長時間運行的方法是這樣執行的:

    public void LongRunningMethod()
    {
        CreateFileProgress= 0;

        // Do some calculations

        CreateFileProgress= 10

        // More calculations and external calls

        CreateFileProgress= 20

        // etc.
    }

但我找不到連接這兩者的正確方法。 我肯定這樣做是錯誤的-希望得到任何指導。 謝謝!

我希望我明白你的問題。 您的 ViewModel 和 View 在同一個項目中,您想監視另一個項目中模型的進度嗎?

我想你正在尋找事件/觀察者模式

在 MVVM 中,模型並不關心 ViewModel 和 View。 MVVM 中的 Prober 方式是模型引發 Viewmodel 可以訂閱的事件。

.Net 中的一般事件示例

您可以創建一個 EventArgs 類,例如

    public class ProgressEventArgs :EventArgs
    {
        public int CurrentProgress { get; }

        public ProgressEventArgs(int progress)
        {
            CurrentProgress = progress;
        }
    }

並在您的模型 (LongRunningMethod) 類中創建事件

    public event EventHandler<ProgressEventArgs> ProgressChanged;
    protected void OnProgressChanged(int progress)
    {
        ProgressChanged?.Invoke(this, new ProgressEventArgs(progress));
    }

所以你的方法可以引發事件

    public void LongRunningMethod()
    {
        OnProgressChanged(0);

        // Do some calculations

        OnProgressChanged(10);

    // More calculations and external calls

        OnProgressChanged(20);

    // etc.
    }

ViewModel 訂閱的

    public class ProgressViewModel
    {
        public ProgressViewModel()
        {
            var model = new Model();
            model.ProgressChanged += (sender, e) => {
                //invoke ui thread
                Application.Current.Dispatcher.Invoke(
                  new Action(() => 
                   {
                     CreateFileProgress = e.CurrentProgress; 
                   }));

            };
        }
    }

似乎最能幫助您的是將您的 UI 元素(窗口、頁面或 ProgressBar 本身)的 DataContext 設置為您的 ViewModel,這將允許您的 UI 綁定到 ViewModel 屬性。 由於您的 ViewModel 似乎實現了 INotifyPropertyChanged 接口,因此您的 OnPropertyChanged() 方法應該在您使用 DataBinding 時自動使 UI 保持最新。

您首先要引用包含“工作”的類庫項目。 這將允許您的“UI 項目”訪問“工作項目”中的資源(即 ViewModel)。 通過下的解決方案資源管理器“UI工程”右擊引用做到這一點,選擇添加引用...,找到左側的項目選項卡,然后勾選你的“工作計划”。 應用它,您的“UI 項目”現在可以訪問您的“工作項目”。

完成后,您可以使用以下任一方法來生成我相信您正在尋找的結果:

將 Window 的 DataContext 設置為您的 ViewModel

(最適合當您的 Window 中的許多元素將使用您的 ViewModel 中的資源時)

<Window
    //Some attributes
    //Some more attributes
    xmlns:vm="clr-namespace:MyWorkProject.ViewModels;assembly=MyWorkProject">        
    <Window.DataContext>
        <vm:MyViewModel/>
    </Window.DataContext>
    <Grid>
        <ProgressBar Value="{Binding CreateFileProgress}/>
    </Grid>
</Window>

或者

使用 StaticResources 僅設置 ProgressBar 的 DataContext

(如果您不需要整個 Window 的 DataContext 作為 ViewModel,則最好)

<Window
    //Some attributes
    //Some more attributes
    xmlns:vm="clr-namespace:MyWorkProject.ViewModels;assembly=MyWorkProject">        
    <Window.Resources>
        <vm:MyViewModel/>
    </Window.Resources>
    <Grid>
        <ProgressBar Value="{Binding Source={StaticResource MyViewModel}, Path=CreateFileProgress}/>
    </Grid>
</Window>

暫無
暫無

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

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