简体   繁体   中英

Caliburn Micro - Share data between ViewModels

Starting from the Caliburn Micro "Simple MDI" example. I would like to achieve the following:

I would like to share the reference of a class between the ViewModels. The shareme.count should be passed as reference to all the ViewModels. This would allow me to change it from within each ViewModel.

How can I achieve this close to Caliburn Micro convention?

ShellViewModel.cs

public class ShellViewModel : Conductor<IScreen>.Collection.OneActive {

SharedClass _shareme;

public SharedClass shareme {
    get { return _shareme; }
    set {
        _shareme = value;
        NotifyOfPropertyChange(() => shareme);
    }
}

public ShellViewModel() {
    shareme.count = 1;
}

public void OpenTab() {
    ActivateItem(new TabViewModel {
        DisplayName = "Tab " + shareme.count++
    });
}

TabViewModel.cs

public class TabViewModel : Screen {}

AppBootstrapper.cs

    public class AppBootstrapper : BootstrapperBase {
    SimpleContainer container;

    public AppBootstrapper() {
        Initialize();
    }

    protected override void Configure() {

        container = new SimpleContainer();

        container.Singleton<IWindowManager, WindowManager>();
        container.Singleton<IEventAggregator, EventAggregator>();
        container.PerRequest<IShell, ShellViewModel>();
    }

    protected override object GetInstance(Type service, string key) {
        var instance = container.GetInstance(service, key);
        if (instance != null)
            return instance;

        throw new InvalidOperationException("Could not locate any instances.");
    }

    protected override IEnumerable<object> GetAllInstances(Type service) {
        return container.GetAllInstances(service);
    }

    protected override void BuildUp(object instance) {
        container.BuildUp(instance);
    }

    protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
    {
        DisplayRootViewFor<IShell>();
    }
}

The will also serve as answer to your duplicate question.

EventAggregator isn't just for "events" you can message pass data to any or all viewmodels that are listening for message or event signature in question.

public class ViewModelA : Screen, IHandle<ShareMeMessageA>
{
  private readonly IEventAggregator _events;
  private int _sharemecount;
  public class ViewModelA(IEventAggregator events){

       _events = events;
       _events.Subscribe(this);
  }

  //... other bits out for brevity 
  //-- EDIT -- 
  public void SomeEventClick(){
    _event.PublishOnUiThread(new ShareMeMessageB(){ ...  etc ... });
  }

  protected override void Deactivated(bool close){
    _events.Unsubscribe(this);
  }

  private void Handle(ShareMeMessageA msg)
  {
      if(msg != null)
        sharemecount = msg.Count;
  }
}

as this is just an example you don't have to pass the class object at all you can pass any type you want bool, int, float, etc..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM