2
votes

I have an UserControl(AutoComplete) with his own ViewModel. When I use the UserControl inside a window, it run well, connect to a service, and paint data correctly. The UserControl datacontext is set via xaml, and is binded to a property of the main window viewModel.

Ok, now I want that the UserControl can load data from the main window view model. The thing is that, supposing the usercontrol loads countries. When I type in the Usercontrol it returns the list of countries and when I select one of them, i.e. "Spain", the SelectedItem property of the Usercontrols updates to "Spain". I want an object in main window viewModel to udate to "Spain" and vice-versa, if I update the country object in the main window viewmodel, the selecteditem of the user should update too.

How can I accomplish that

I have this in my mainview:

<amctrls:AmAutoCompleteView DataContext="{Binding controladorAutoCompleteCountry}" /> 

the user control loks like this:

<telerik:RadComboBox Margin="2,0,0,0" Grid.Row="0" Grid.Column="0"  
            IsEditable="True"
            Name="RadCbo"
            ItemsSource="{Binding objectList}" 
            DisplayMemberPath="{Binding fieldToShow}"
            OpenDropDownOnFocus="True"
            SelectedItem="{Binding selectedCountry, Mode=TwoWay}"
            Text="{Binding searchText, Mode=TwoWay}"
            IsTextSearchEnabled="False" 
            StaysOpenOnEdit="True" />

controladorAutoCompleteCountry is a property of my mainview wih is an instance of the usercontrol viewmodel.

The viewmodel of the main view manage addresses, and what I want is to bind an address country to the usercontrol in order to edit the address. If i have the usercontrol binded to an instance of its controller, how can I bind the Country object of the address?

2
Can you post some code? Ideally, a simplified version of your xaml markup with only the relevant bindings etc. Also, the MainViewModel with only the relevant properties etc.bic
From what I understand you have a view BetaView with a combobox, that is loaded into a view AlphaView. However, you want to bind the BetaView-combobox to both BetaViewModel and AlphaViewModel properties?Deruijter
yes but datacontext of each view are different, main view has its view model and the user control has its own. I made this because the user control has its own behavior, but the data it manipulates should affect data in mainview context. (Country of an address). Mybe it's not the right way to do this...user1549473

2 Answers

1
votes

If you need to make those 2 views independent which is good if you want to reuse your control, go with Event Aggregator or simple events. Whenever an item is selected in the user control, it will publish an event stating, something interesting has happened. Main viewmodel can subscribe to those events and do the required. A simple case would be a creating a static class with an event and RaiseEvent method, user control will RaiseEvent and main viewmodel with be subscribing the event. Data to be passed between them can be added to the event args.

0
votes

It's a bit the other way around, but you can try something like this:

Have a MainView with a

  • combobox that is bound to the string property SelectedCountry and method ChangeCountry()
  • ContentControl that is bound to CountryInfoViewModel property SelectedCountryControl

You can now bind your combobox to the CountryInfoViewModel that is loaded in your MainView.

Below is an example that worked for me (note that I used caliburn micro here). It basicly updates the CountryInfoViewModel/View when a different country has been selected. You could improve the ChangeCountry method to get all the data, and of course improve the CountryInfoViewModel/View to show everything you want shown.

MainViewModel

class MainViewModel : Screen
{
    #region fields

    private BindableCollection<string> _listOfCountries;
    private string _selectedCountry;
    private CountryInfoViewModel _selectedCountryControl;

    #endregion fields

    #region properties

    public BindableCollection<string> ListOfCountries
    {
        get
        {
            return new BindableCollection<string>
                       {
                           "France",
                           "Holland",
                           "Russia"
                       };
        }
    }

    public string SelectedCountry
    {
        get { return _selectedCountry; }
        set
        {
            _selectedCountry = value;
            NotifyOfPropertyChange(() => SelectedCountry);
        }
    }

    public CountryInfoViewModel SelectedCountryControl
    {
        get { return _selectedCountryControl; }
        set
        {
            _selectedCountryControl = value;
            NotifyOfPropertyChange(() => SelectedCountryControl);
        }
    }

    #endregion properties

    public MainViewModel()
    {
        SelectedCountry = "Holland";
        ChangeCountry();
    }

    public void ChangeCountry()
    {
        SelectedCountryControl = new CountryInfoViewModel()
                                   {
                                       CountryName = SelectedCountry
                                   };
    }
}

MainView:

<UserControl x:Class="WpfModifyDifferentView.Views.MainView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel>
        <ComboBox x:Name="ChangeCountry" SelectedItem="{Binding SelectedCountry}" ItemsSource="{Binding ListOfCountries}"/>
        <ContentControl x:Name="SelectedCountryControl"/>
    </StackPanel>
</UserControl>

CountryInfoViewModel:

class CountryInfoViewModel : Screen
{
    #region fields

    private string _countryName;

    #endregion fields

    #region properties

    public string CountryName
    {
        get { return _countryName; }
        set
        {
            _countryName = value;
            NotifyOfPropertyChange(() => CountryName);
        }
    }

    #endregion properties

}

CountryInfoView:

<UserControl x:Class="WpfModifyDifferentView.Views.CountryInfoView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel Orientation="Vertical">
        <TextBlock Text="You have chosen the country:"/>
        <TextBlock x:Name="CountryName"/>
    </StackPanel>
</UserControl>