gpt4 book ai didi

c# - 将 SelectedItem 传递给 DataTemplate 中 UserControl 的 ViewModel

转载 作者:行者123 更新时间:2023-12-03 10:25:49 25 4
gpt4 key购买 nike

我有这个用 Prism 制作的非常简单的 MVVM 代码:

  • 2 个模型(Person、Company - 公共(public)接口(interface) IContact),带有 2 个 ViewModel(Prism)和 2 个 View(UserControl)
  • 1 个 ViewModel(接口(interface) IContact 的集合)和 1 个 View(ListBox 绑定(bind)到集合,ContentControl 绑定(bind)到 ListBox 的 SelectedItem,DataTemplateSelector 根据 SelectedItem 的类型返回两个 UserControl 之一)

  • 如何将模型对象(Person 或 Company)从 ListBox 的 SelectedItem (IContact) 传递到与 DataTemplateSelector(PersonView 或 CompanyView)返回的 View 匹配的两个 ViewModel(PersonViewModel 或 CompanyViewModel)之一?

    谢谢!

    代码很多,但其实很简单:

    我有这些模型类:
    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); }
    }
    }

    我有这些 View 类:
    <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;
    }
    }
    }

    最佳答案

    不要在此处先使用 View (又名 ViewModelLocator)。先去查看模型。

    长版:

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

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

    当您已经拥有要显示的项目(即其 View 模型)时,只需绑定(bind)并显示该项目。如果您想导航到应用程序中的某个屏幕(例如登录对话框),请使用 ViewModelLocator .它基本上是没有准备好 View 模型的解决方法。

    关于c# - 将 SelectedItem 传递给 DataTemplate 中 UserControl 的 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53499400/

    25 4 0
    文章推荐: c# - 指定的强制转换不是FreshMvvm Xamarin中的无效异常
    文章推荐: c# - 如何根据另一个字段的值使一个字段成为必填字段
    文章推荐: c# - 来自列表 的组合框 DisplayMemberPath