C# WPF ListView SelectedItem未使用DataTemplate中的扩展器更新

C# WPF ListView SelectedItem未使用DataTemplate中的扩展器更新,c#,wpf,listview,C#,Wpf,Listview,我正在使用C和MVVM创建一个WPF应用程序,但在ListView的SelectedItem中遇到了一些问题 在虚构的示例中,场景是:我有一个PersonViewModel,其中包含Person对象列表。每个person对象都有自己的地址对象列表。我的目标是将所有Person对象加载到ListView中。此外,ListView数据模板应包括显示每个人可用地址的扩展器 问题是:这一切实际上已经足够体面了。唯一的问题是,如果用户为person对象选择扩展器,它实际上不会更改ListView的Sele

我正在使用C和MVVM创建一个WPF应用程序,但在ListView的SelectedItem中遇到了一些问题

在虚构的示例中,场景是:我有一个PersonViewModel,其中包含Person对象列表。每个person对象都有自己的地址对象列表。我的目标是将所有Person对象加载到ListView中。此外,ListView数据模板应包括显示每个人可用地址的扩展器

问题是:这一切实际上已经足够体面了。唯一的问题是,如果用户为person对象选择扩展器,它实际上不会更改ListView的SelectedItem属性,该属性绑定到视图模型中的SelectedPerson对象

我相对确信代码在其他情况下是有效的,因为如果我在包含的扩展程序的边界之外单击ListView行,SelectedPerson属性就会更新。当扩展器被单击到SelectedPerson属性时,是否仍然存在某种绑定?我也愿意接受其他UI想法,这些想法将以更干净、更容易实现的方式传达我的信息

Person.cs

PersonViewModel.cs


由于视图模型包含单个SelectedPerson属性,因此在datatemplate中包含扩展器对我来说没有意义。如果你能改变你的用户界面,下面的例子对我来说似乎更有意义。显然,你可以把地址“面板”放在任何你喜欢的地方

另外,您是否尝试过从子列表视图中选择地址?装订行吗

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>

    <ListView ItemsSource="{Binding People, Mode=TwoWay}"    
              SelectedItem="{Binding SelectedPerson}"
              DisplayMemberPath="Name">           
    </ListView>

    <ListView Grid.Column="1" 
              ItemsSource="{Binding SelectedPerson.Addresses, Mode=TwoWay}" 
              SelectedItem="{Binding SelectedAddress}">
        <ListView.View>
            <GridView>
                <GridViewColumn Width="50" Header="Number" DisplayMemberBinding="{Binding HouseNumber}" />
                <GridViewColumn Width="100" Header="Street" DisplayMemberBinding="{Binding StreetName}" />
                <GridViewColumn Width="100" Header="City" DisplayMemberBinding="{Binding City}" />
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

谢谢你的反馈。我曾试图将所有内容都保存在一个listview中,以便将其整齐地分组,但在实现了您的解决方案之后,我意识到,通过包含扩展器,除了不必要的复杂性之外,我并没有获得任何东西。谢谢你的建议。它工作得很好。
namespace ListViewExpanderTest
{
    public class Address
    {
        public int HouseNumber { get; set; }
        public string StreetName { get; set; }
        public string City { get; set; }
    }
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace ListViewExpanderTest
{
    public class PersonViewModel : INotifyPropertyChanged
    {
        private Person _selectedPerson;
        private Address _selectedAddress;

        public List<Person> People { get; set; }
        public Person SelectedPerson
        {
            get
            {
                return _selectedPerson;
            }
            set
            {
                _selectedPerson = value;
                OnPropertyChanged();
            }
        }

        public Address SelectedAddress
        {
            get
            {
                return _selectedAddress;
            }
            set
            {
                _selectedAddress = value;
                OnPropertyChanged();
            }
        }

        public PersonViewModel()
        {
            People = new List<Person>
            {
                new Person
                {
                    Name = "Person 1",
                    Addresses = new List<Address>
                    {
                        new Address {HouseNumber = 1, StreetName = "Fake St", City = "Fake City" },
                        new Address {HouseNumber = 2, StreetName = "Super Fake St", City = "Super Fake City" }
                    }
                },
                new Person
                {
                    Name = "Person 2",
                    Addresses = new List<Address>
                    {
                        new Address {HouseNumber = 10, StreetName = "Fake St", City = "Fake City" },
                        new Address {HouseNumber = 20, StreetName = "Super Fake St", City = "Super Fake City" }
                    }
                }
            };
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
<Window x:Class="ListViewExpanderTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ListViewExpanderTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:PersonViewModel />
    </Window.DataContext>
    <Grid>
        <ListView ItemsSource="{Binding People, Mode=TwoWay}"
                  SelectedItem="{Binding SelectedPerson}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Expander >
                        <Expander.Header>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding Name}" />
                            </StackPanel>
                        </Expander.Header>
                        <Expander.Content>
                            <ListView ItemsSource="{Binding Addresses, Mode=TwoWay}"
                                      SelectedItem="{Binding SelectedAddress}">
                                <ListView.View>
                                    <GridView>
                                        <GridViewColumn Width="50" Header="Number" DisplayMemberBinding="{Binding HouseNumber}" />
                                        <GridViewColumn Width="100" Header="Street" DisplayMemberBinding="{Binding StreetName}" />
                                        <GridViewColumn Width="100" Header="City" DisplayMemberBinding="{Binding City}" />
                                    </GridView>
                                </ListView.View>
                            </ListView>
                        </Expander.Content>
                    </Expander>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Window>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>

    <ListView ItemsSource="{Binding People, Mode=TwoWay}"    
              SelectedItem="{Binding SelectedPerson}"
              DisplayMemberPath="Name">           
    </ListView>

    <ListView Grid.Column="1" 
              ItemsSource="{Binding SelectedPerson.Addresses, Mode=TwoWay}" 
              SelectedItem="{Binding SelectedAddress}">
        <ListView.View>
            <GridView>
                <GridViewColumn Width="50" Header="Number" DisplayMemberBinding="{Binding HouseNumber}" />
                <GridViewColumn Width="100" Header="Street" DisplayMemberBinding="{Binding StreetName}" />
                <GridViewColumn Width="100" Header="City" DisplayMemberBinding="{Binding City}" />
            </GridView>
        </ListView.View>
    </ListView>
</Grid>