how to Subscribe event from specified View?

Sep 21, 2010 at 4:32 AM

i have two regions "RegionA" and "RegionB",

and a View contains one ListBox:   ISectionListView ,

<ListBox Style="{StaticResource ListBoxStyle}"
                 ItemsSource="{Binding Sections}"
                 ItemTemplate="{StaticResource SectionTemplate}"
                 SelectedItem="{Binding SelectedSection, Mode=TwoWay}">
           
</ListBox>

and in the ISectionListViewModel, i publish the Listbox's Item Selected Event:

public class SectionListViewModel : ViewModelBase<ISectionListView>, ISectionListViewModel

        public v_wq_section SelectedSection
        {
            get { return this._selectedSection; }
            set
            {
                this._selectedSection = value;
                this._eventAggregator.GetEvent<Events.SectionSelectedEvent>()
                .Publish(new Events.SectionSelectedEvent(value));
            }
        }

and now I register the  View in both "RegionA" and "RegionB":

this._regionManager.RegisterViewWithRegion("RegionA", () => this._container.Resolve<ISectionListViewModel>().View);

this._regionManager.RegisterViewWithRegion("RegionB", () => this._container.Resolve<ISectionListViewModel>().View);

 

in another module i  Subscribe the Events.SectionSelectedEvent:

this._eventAggregator.GetEvent<Wq_Section.Events.SectionSelectedEvent>()
                .Subscribe(OnSectionSelected);

now the problem comes,i just want to Subscribe Events.SectionSelectedEvent  from the ListBox in "RegionA", but it also Subscribe Events.SectionSelectedEvent  from the ListBox in "RegionB".

it's the problem.

i notice that CompositePresentationEvent.Subscribe() method has one  parameter "filterReference", can it solve this problem ? and how?

thanks!!!

 

 

Sep 21, 2010 at 3:47 PM

Hi,

In general, a ViewModel does not know in which region its view is displayed. Although passing the region name might be an approach that works, this is not recommended because it couples the VM and the Region that contains its view. If that wasn’t the case using a subscription filter would probably be a good way to go.

That said, another option could be to indicate an event type when you create your viewmodel (EventTypeA or EventTypeB). This way you could publish two different events.

On the other hand, as you mentioned the solution for your scenario is to use a subscription filter. For more information, you could take a look at the following documentation section on MSDN:

As for how to implement this, you need to use View Injection to indicate in which region you are adding the view, so the view could indicate to its viewmodel the Region:

In the module initialize:  regionA.Add(new ViewA(“RegionA”), "View 1");

In the view: this.DataContext = new MyViewModel(“RegionA”);

If you need more information about how to use View Injection, you could check it here.

Therefore, you would publish your event indicating the region (pseudo-code):

EventAggregator.GetEvent<YourEvent>().Publish(“RegionA”);

Then you could filter a subscription by supplying a delegate as is shown below (pseudo-code):

yourEvent.Subscribe(yourEventHandler, ThreadOption.UIThread, false, view => view == “RegionA”);

I hope this helps,

Fernando Antivero
http://blogs.southworks.net/fantivero