![](/img/trans.png)
[英]Change Background Color of SelectedItem from WPF ListView with Custom DataTemplate
[英]WPF ListView SelectedItem Not Updating With Expander in DataTemplate
我正在使用 C# 和 MVVM 創建一個 WPF 應用程序,但我在使用 ListView 的SelectedItem
時遇到了一些問題。
在人為的示例中,場景:我有一個包含Person
對象列表的PersonViewModel
。 每個人 object 都有自己的Address
對象列表。 我的目標是將所有 Person 對象加載到ListView
中。 此外, ListView DataTemplate
應包括顯示每個人可用地址的擴展器。
問題:這一切實際上都足夠體面。 唯一的問題是,如果用戶為人員選擇擴展器 object,它實際上不會更改ListView
的SelectedItem
屬性(它綁定到視圖模型中的 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.