在usercontrol和主视图之间共享数据

时间:2012-07-26 12:25:56

标签: wpf mvvm view user-controls

我有一个UserControl(AutoComplete)和他自己的ViewModel。当我在窗口中使用UserControl时,它运行良好,连接到服务,并正确绘制数据。 UserControl datacontext通过xaml设置,并绑定到主窗口viewModel的属性。

好的,现在我希望UserControl可以从主窗口视图模型加载数据。问题是,假设用户控件加载国家。当我输入Usercontrol时,它返回国家列表,当我选择其中一个,即“Spain”时,Usercontrols的SelectedItem属性更新为“Spain”。我希望主窗口viewModel中的对象更新为“西班牙”,反之亦然,如果我在主窗口viewmodel中更新country对象,则用户的selecteditem也应该更新。

我怎样才能实现

我在主视图中有这个:

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

用户控件像这样:

<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是我的主视图的属性wih是usercontrol viewmodel的一个实例。

主视图的viewmodel管理地址,我想要的是将地址国家/地区绑定到usercontrol以编辑地址。如果我将usercontrol绑定到其控制器的实例,我该如何绑定该地址的Country对象?

2 个答案:

答案 0 :(得分:1)

如果您需要使这两个视图独立,如果您想重用您的控件,那么请使用Event Aggregator或简单事件。每当在用户控件中选择一个项目时,它将发布一个事件,说明发生了一些有趣的事情。主视图模型可以订阅这些事件并执行所需的操作。一个简单的例子是创建一个带有事件和RaiseEvent方法的静态类,用户控件将RaiseEvent和主视图模型与订阅事件。可以将它们之间传递的数据添加到事件参数中。

答案 1 :(得分:0)

这有点相反,但你可以尝试这样的事情:

使用

创建一个MainView
  • combobox绑定到字符串属性SelectedCountry和方法ChangeCountry()
  • 绑定到CountryInfoViewModel属性的
  • ContentControl SelectedCountryControl

您现在可以将组合框绑定到MainView中加载的CountryInfoViewModel。

以下是一个适用于我的示例(请注意,我在这里使用了caliburn micro)。 当选择了其他国家/地区时,它会基本更新CountryInfoViewModel / View。 您可以改进ChangeCountry方法以获取所有数据,当然还可以改进CountryInfoViewModel / View以显示您想要显示的所有内容。

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>