多个视图模型共享带有通知的服务 [英] Multiple viewmodels sharing a service with notification

查看:63
本文介绍了多个视图模型共享带有通知的服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:我有两个与一个列表共享服务的视图模型.我的问题是如何设置通知,以便两个视图模型都知道何时更改此列表.下面的描述以及我所在的位置的代码.

Question: I have two viewmodels that share a service with a list. My question is how to setup the notification so that both viewmodels know when this list is changed. Description below and code of where i'm at.

我找到了这个示例 HERE ,它看起来很符合我的尝试,但是我有一个疑问如何在我的视图模型中通知我服务的更改.我将添加一些我已模拟的代码,以查看我是否处在正确的轨道上.我正在使用WPF/MVVM Light.

I found this example HERE that looks right for what I'm trying to do, but I have a question regarding how to be notified in my viewmodels of a change in my service. I'll add some code I've mocked up to see if I'm on the right track. I'm using WPF/MVVM Light.

第一部分是带有接口的服务,该接口将具有数据列表,在此示例中,我使用的是字符串列表.我希望两个视图模型中的一个属性都可以访问此数据列表,并在数据更改时得到通知.我认为让我吃惊的是我的视图模型中的接口IOC.我越来越了解这为什么很好,但是我仍在思考,我不确定在服务中更改列表时如何设置通知.如果未注入我的服务,则可能已经设置了一个事件或属性,我的viewmodel属性将访问该事件或属性,但注入我的服务不会公开我的公共字段,而只是公开方法.这对我来说是新的,所以很可能我无法正确理解或缺少某些内容.

First part is a service with a interface that will have a list of data, in this example I'm using a string list. I want a property in both viewmodels to have access to this list of data, and be notified when it's changed. I think what's throwing me is the interface IOC into my viewmodels. I'm understanding more and more why this is good, but I'm still wrapping my mind around it and I'm not sure how to setup the notification when the list is changed in the service. If my service was not injected I might have setup a event or property that my viewmodel property would access get/set but injecting my service does not expose my public fields, just methods. This is new to me so it's very likely i'm not understanding this correctly or missing something.

基于我在此处对使用ObservableCollection所做的警告的某些阅读,我在服务中使用了List而不是ObservableCollection.谢谢您的帮助.

I used a List in my service instead of a ObservableCollection based on some reading I've done warning against using the ObservableCollection here. Thanks you for any help.

public class MyService : IMyService
{
    private List<string> myList = new List<string>();

    public List<string> getMyList()
    {
        return this.myList;
    }
    public void setMyList(List<string> value)
    {
        this.myList = value;
    }
    public void addValue(string value)
    {
        this.myList.Add(value);
    }
    public void insertValue(int index, string value)
    {
        this.myList.Insert(index, value);
    }
}

public class MyViewModelOne : ViewModelBase
{
    private readonly IMyService myService;

    public MyViewModelOne(IMyService myService)
    {
        this.myService = myService;
    }

    public List<string> MyProperty // control item source will bind to this
    {
        get
        {
            return this.myService.getSource();
        }
    }
    public void setSomeValue(value)
    {
        this.myService.addValue(value);
    }
}

public class MyViewModelTwo : ViewModelBase
{
    private readonly IMyService myService;

    public MyViewModelTwo(IMyService myService)
    {
        this.myService = myService;
    }

    public List<string> MyProperty // control item source will bind to this
    {
        get
        {
            return this.myService.getSource();
        }
    }
    public void setSomeValue(value)
    {
        this.myService.addValue(value);
    }
}

推荐答案

我以两种不同的方式工作,我选择了第一个示例,因为我认为在代码中更容易理解.

I got this working two different ways, I went with the first example because I think it's easier to follow in the code.

之所以出现这个问题,是因为我在主视图中有一个控件,并且该控件的相关代码正在增长,并且我意识到我希望在单独的视图中使用相同的控件/行为,而将相同的数据/控件用于不同的目的. 我不想在两个地方重复此控件/模板/代码,因此将其制作为用户控件.然后,将用户控件嵌套在我的视图中.用户控件具有自己的VM.主视图使用新数据更新服务,并且嵌套控件侦听事件以知道何时有新数据.

This came up because I had a control in my mainview with related code that was growing and I realized I wanted the same control/behavior in a separate view that would use the same data/control for a different purpose. I did not want to duplicate this control/template/code in two places so I made it into a User Control. I then nest the user control in my views. The user control has it's own VM. The main view updates the service with new data, and the nested control listens on a event to know when there is new data.

对于MVVM思维还是非常新颖的,所以请随时指出这些示例中的任何一个问题.

Still very new to MVVM thinking so please feel free to point out in issues with either of these examples.

通过事件处理程序使用服务的示例.

public interface IMyInterface
{   
    event EventHandler OnSomeEvent;
    void addSomeData(string value);
    void getSomeData();
}

public class MyInterface: IMyInterface
{
    public event EventHandler OnSomeEvent = delegate { };  

    public void addSomeData(string value)
    {
        // do stuff
        OnSomeEvent();
    }
    public string getSomeData()
    {
        return "some data";
    }
}

// Main ViewModel
public class ViewModelOne : ViewModelBase
{
    IMyInterface myInterface;
    public NotifyViewModel(IMyInterface myInterface)
    {
        this.myInterface = myInterface;
        this.myInterface.OnItemSourceChanged += myInterface_OnSomeEvent;
    }

    void testEvent()
    {
        this.myInterface.addSomeData("test data");
    }
}

// My nested user control
public class ViewModelTwo : ViewModelBase
{
    IMyInterface myInterface;
    public NotifyViewModel(IMyInterface myInterface)
    {
        this.myInterface = myInterface;
        this.myInterface.OnItemSourceChanged += myInterface_OnSomeEvent;
    }

    void myInterface_OnSomeEvent(object sender, System.EventArgs e)
    {
        // do stuff
    }
}

使用MVVM Light Messaging的示例

public class EventDataSource
{
    public string MyItemSource { get; set; }
    public EventDataSource()
    {
        MyItemSource = string.Empty;
    }

}

// Message class
public class MyDataSourceMessage : MessageBase
{
    public EventDataSource MyItemSource { get; set; }
    public MyDataSourceMessage(EventDataSource myItemSource)
    {
        MyItemSource = myItemSource;
    }
}

// Main ViewModel
public class ViewModelOne : ViewModelBase
{
    public NotifyViewModel() {}

    void testMessage()
    {
        EventDataSource msg = new EventDataSource() { MyItemSource = "magic message!"};
        Messenger.Default.Send(new MyDataSourceMessage(msg as EventDataSource));
    }
}

// My nested user control
public class ViewModelTwo : ViewModelBase
{

    public NotifyViewModel()
    {
        Messenger.Default.Register<MyDataSourceMessage>(this, (action) => ReceiveMessage(action));
    }

    private ObservableCollection<string> myProperty = new ObservableCollection<string>();
    public ObservableCollection<string> MyProperty
    {
        get { return myProperty; }
        set
        {
            myProperty: = value;
            RaisePropertyChanged(() => MyProperty);
        }
    }
    void ReceiveMessage(MyDataSourceMessage action)
    {
        // do something with the data
        MyProperty.Add(action.DGItemSource.ItemSource);
    }
}

这篇关于多个视图模型共享带有通知的服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆