簡體   English   中英

WPF ListView SelectedItem 未使用 DataTemplate 中的擴展器更新

[英]WPF ListView SelectedItem Not Updating With Expander in DataTemplate

我正在使用 C# 和 MVVM 創建一個 WPF 應用程序,但我在使用 ListView 的SelectedItem時遇到了一些問題。

在人為的示例中,場景:我有一個包含Person對象列表的PersonViewModel 每個人 object 都有自己的Address對象列表。 我的目標是將所有 Person 對象加載到ListView中。 此外, ListView DataTemplate應包括顯示每個人可用地址的擴展器。

問題:這一切實際上都足夠體面。 唯一的問題是,如果用戶為人員選擇擴展器 object,它實際上不會更改ListViewSelectedItem屬性(它綁定到視圖模型中的 SelectedPerson object)。

我相對確信代碼可以正常工作,因為如果我單擊 ListView 行(在包含的擴展器的邊界之外),則SelectedPerson屬性會更新。 當擴展器被單擊到 SelectedPerson 屬性時,是否有某種方式綁定? (我也對其他 UI 想法持開放態度,這些想法將以更清晰、更容易實現的方式傳達我的信息)。

Person.cs

using System.Collections.Generic;

namespace ListViewExpanderTest
{
    public class Person
    {
        public Person()
        {
            Addresses = new List<Address>();
        }
        public string Name { get; set; }
        public List<Address> Addresses { get; set; }
    }
}

Address.cs

namespace ListViewExpanderTest
{
    public class Address
    {
        public int HouseNumber { get; set; }
        public string StreetName { get; set; }
        public string City { get; set; }
    }
}

PersonViewModel.cs

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));
        }
    }
}

MainWindow.xaml

<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>

正如您的觀點 model 包含一個SelectedPerson屬性,在數據模板中包含擴展器對我來說沒有意義。 如果您可以更改您的 UI,那么下面的示例對我來說似乎更有意義。 您顯然可以將地址“面板”放置在您喜歡的任何地方。

另外,您是否嘗試過從子列表視圖中選擇地址? 綁定有用嗎?

<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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM