代码之家  ›  专栏  ›  技术社区  ›  Jinjinov

将SelectedItem传递到DataTemplate内的UserControl的ViewModel

  •  1
  • Jinjinov  · 技术社区  · 6 年前

    我有一个用prism编写的非常简单的mvvm代码:

    • 2个模型(个人、公司-公共接口IContact),2个视图模型(prism)和2个视图(usercontrol)
    • 1个视图模型(接口IContact的集合),其中1个视图(列表框绑定到集合,一个ContentControl绑定到列表框的SelectedItem,数据模板Selector根据SelectedItem的类型返回两个用户控件中的一个)

    如何将模型对象(个人或公司)从列表框的SelectedItem(IContact)传递到与DataTemplateSelector返回的视图(个人视图或公司视图)匹配的两个视图模型之一?

    谢谢您!


    代码很多,但很简单:

    我有这些模型类:

    public interface IContact
    {
        string Address { get; set; }
    }
    
    public class Person : IContact
    {
        public string Address { get; set; }
    }
    
    public class Company : IContact
    {
        public string Address { get; set; }
    }
    

    我有以下ViewModel类:

    public class ContactViewModel : Prism.Mvvm.BindableBase
    {
        private ObservableCollection<IContact> _contacts = new ObservableCollection<IContact>();
        public ObservableCollection<IContact> Contacts
        {
            get { return _contacts; }
            set { SetProperty(ref _contacts, value); }
        }
    }
    
    public class PersonViewModel : Prism.Mvvm.BindableBase
    {
        private Person _person; // I want to set this from the ListBox's SelectedItem
        public Person Person
        {
            get { return _person; }
            set { SetProperty(ref _person, value); }
        }
    }
    
    public class CompanyViewModel : Prism.Mvvm.BindableBase
    {
        private Company _company; // I want to set this from the ListBox's SelectedItem
        public Company Company
        {
            get { return _company; }
            set { SetProperty(ref _company, value); }
        }
    }
    

    我有这些视图类:

    <UserControl x:Class="ContactView"
                 xmlns:prism="http://prismlibrary.com/"
                 prism:ViewModelLocator.AutoWireViewModel="True" >
        <UserControl.Resources>
            <DataTemplate x:Key="PersonDataTemplate">
                <local:PersonView>
                    // How can I pass the SelectedItem to the ViewModel of this UserControl?
                </local:PersonView>
            </DataTemplate>
            <DataTemplate x:Key="CompanyDataTemplate">
                <local:CompanyView>
                    // How can I pass the SelectedItem to the ViewModel of this UserControl?
                </local:CompanyView>
            </DataTemplate>
            <dataTemplateSelectors:contactDataTemplateSelector x:Key="templateSelector"
                  PersonDataTemplate="{StaticResource PersonDataTemplate}" 
                  CompanyDataTemplate="{StaticResource CompanyDataTemplate}"/>
        </UserControl.Resources>
        <Grid>
            // RowDefinitions here
            <ListBox ItemsSource="{Binding Contacts}" x:Name="myListBox">
                // ItemTemplate here
            </ListBox>
            <ContentControl Grid.Row="1" 
                Content="{Binding ElementName=myListBox, Path=SelectedItem}" 
                ContentTemplateSelector="{StaticResource templateSelector}" />
        </Grid>
    </UserControl>
    

    人:

    <UserControl x:Class="PersonView"
                 xmlns:prism="http://prismlibrary.com/"
                 prism:ViewModelLocator.AutoWireViewModel="True" >
        <Grid>
            <TextBlock Text="{Binding Person.Address}" />
        </Grid>
    </UserControl>
    

    公司:

    <UserControl x:Class="CompanyView"
                 xmlns:prism="http://prismlibrary.com/"
                 prism:ViewModelLocator.AutoWireViewModel="True" >
        <Grid>
            <TextBlock Text="{Binding Company.Address}" />
        </Grid>
    </UserControl>
    

    还有这个:

    public class ContactDataTemplateSelector : DataTemplateSelector
    {
        public DataTemplate PersonDataTemplate { get; set; }
        public DataTemplate CompanyDataTemplate { get; set; }
    
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            if (item is Person)
            {
                return PersonDataTemplate;
            }
            if (item is Company)
            {
                return CompanyDataTemplate;
            }
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Haukinger    6 年前

    不要先使用视图(A.K.A. ViewModelLocator 在这里。先查看模型。

    长版本:

    制作 Contacts (列表框的项源)包含视图模型。然后直接绑定 SelectedItem 到内容控件。

    列表框使用一个数据模板显示联系人,内容控件使用另一个。你甚至不需要选择器,只要设置 DataType 在您的数据模板上。

    当您已经有了要显示的项目(即视图模型)时,只需绑定并显示该项目即可。如果要导航到应用程序中的屏幕(例如登录对话框),请使用 视图模型定位器 . 它基本上是一个解决方案 准备好视图模型。