开发者

Cannot seem to communicate between views

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


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 :)


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜