从另一个项目中的Method设置ViewModel属性

时间:2017-10-27 20:49:13

标签: c# wpf mvvm

初学者 - 我正在努力绕过访问viewmodel属性。在我的特定情况下,我有一个包含两个不同项目的解决方案。一个包含UI组件,另一个包含大部分“工作”。

我的UI项目中的viewmodel包含以下属性:

   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.
    }

但我找不到连接这两者的正确方法。我肯定这样做错了 - 会感谢任何指导。谢谢!

2 个答案:

答案 0 :(得分:1)

我希望我理解你的问题。 您的ViewModel和View是否在同一个Project中,您是否希望监视另一个项目中Model的进度?

我认为您正在搜索事件/观察者模式

在MVVM中,Model并不关心ViewModel和View。 MVVM中的Prober Way是模型引发Viewmodel可以订阅的事件。

.Net中的常规事件示例

您可以创建一个类似

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

并在模型(LongRunningMethod)类

中创建事件
    public void LongRunningMethod()
    {
        OnProgressChanged(0);

        // Do some calculations

        OnProgressChanged(10);

    // More calculations and external calls

        OnProgressChanged(20);

    // etc.
    }

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

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

            };
        }
    }

ViewModel订阅

executable_path

答案 1 :(得分:0)

似乎最有帮助的是将UI元素的DataContext(Window,Page或ProgressBar本身)设置为ViewModel,这将允许您的UI绑定到ViewModel属性。由于ViewModel似乎实现了INotifyPropertyChanged接口,因此当您使用DataBinding时,OnPropertyChanged()方法应该自动使UI保持最新。

您首先要引用包含“work”的类库项目。这将允许您的“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>

OR

使用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>