tags:

views:

211

answers:

2

Hi all

I have written a MVVM prototype as a learning exercise and I am struggling to understand how I can communicate between views.Let me explain

I have a treeview on the left (leftSideView)

ListView on the right (rightSideView)

MainWindow (includes the 2 views mentioned above and a splitter)

What I have implemented does not work and I would like you if you can point out where I am going wrong or if there is a better way of doing it. you can download the quick prototype from here

http://cid-9db5ae91a2948485.skydrive.live.com/self.aspx/.Public/WpfCommunicationBetweenViews.zip

For sure I am doing something wrong with the bindind. Also it would be nice to learn how you do it. EG ListBox on left (one view) ListView On the right (another view) how u communicate between the two.

Thanks a lot of any suggestions

+2  A: 

I took a look at your code, made the modifications shown below, and it worked. I changed the right side view to just have a textblock to simplify it a bit.

MainWindow.xaml.cs (Create a view model for both views to bind to)

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
    }

    public static ProtoViewModel MainViewModel = new ProtoViewModel(Repository.GetContinents());
}

LeftSideView.xaml.cs (set the data context of this view to be the view model and update the selected city of the view model when changed)

public partial class LeftSideView
{
    public LeftSideView()
    {
        InitializeComponent();

        this.DataContext = MainWindow.MainViewModel;
    }

    /// <summary>
    /// Update the selected city of the view model
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void OnTreeSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        (this.DataContext as ProtoViewModel).SelectedCity = e.NewValue as CityViewModel;
    }
}

RightSideView.xaml.cs (set the right side view to use the same view model)

public partial class RightSideView
{
    public RightSideView()
    {
        InitializeComponent();

        this.DataContext = MainWindow.MainViewModel;
    }
}

In the RightSideView.xaml, I just put the textbox that is shown below:

<TextBlock Text="{Binding SelectedCity.Details.City.Name}"/>

When a city on the left view is selected, it will changed the selected city on the view model, therefore, it will updated the selected city name on the right view.

Here's what the ProtoViewModel class looked like:

public class ProtoViewModel : Core.ViewModelBase
{
    public ProtoViewModel(IEnumerable<ContinentInfo> continents)
    {
        Continents =
            new ReadOnlyCollection<ContinentViewModel>(
                (from continent in continents
                 select new ContinentViewModel(continent)).ToList());
    }

    public ViewModels.CityViewModel SelectedCity
    {
        get { return selectedCity; }
        set
        {
            if(selectedCity != value)
            {
                selectedCity = value;
                OnPropertyChanged("SelectedCity");
            }
        }
    }
    private ViewModels.CityViewModel selectedCity;

    public ReadOnlyCollection<ContinentViewModel> Continents
    {
        get { return continents; }
        set
        {
            if (continents != value)
            {
                continents = value;
                OnPropertyChanged("Continents");
            }
        }
    }
    private ReadOnlyCollection<ContinentViewModel> continents;
}

I would share the modified files with you, but I'm not sure how to do that :)

JSprang
wow .Let me digest it and come back you.you could if you want to email me [email protected] but not to worry if a hassle.I know there are many ways to skin a cat but would you have done it this way?Just trying to establish what is the correct way.I have been reading about "Messenger" Mediator pattern etc... just not sure what is a sort of "Best practice" if you like.
A: 

You might also consider using a loosely-coupled Mediator pattern. See for example:

Laurent Bugnion's Mediator in the MVVM Light Toolkit here

MVVM Foundation's Messenger here

Prism's Event Aggregator here

Josh Twist's ISuckLessEventAggregator here

David Cuccia