C# 如何在多选项目时从Listview获取最后一个项目
我对multiselect和SelectedItem属性有点问题。我的应用程序的工作方式如下:当我在Listview中单击一条记录时,该记录中的数据显示在文本框中。现在是我的问题。我想实现这样的功能:当我一个接一个地点击一条记录时,我想显示上一个选中项目的数据。不幸的是,SelectedItem只对第一个元素有效。你能帮我吗?我附上了代码的必要部分: MainWindow.xamlC# 如何在多选项目时从Listview获取最后一个项目,c#,wpf,mvvm,multi-select,selecteditem,C#,Wpf,Mvvm,Multi Select,Selecteditem,我对multiselect和SelectedItem属性有点问题。我的应用程序的工作方式如下:当我在Listview中单击一条记录时,该记录中的数据显示在文本框中。现在是我的问题。我想实现这样的功能:当我一个接一个地点击一条记录时,我想显示上一个选中项目的数据。不幸的是,SelectedItem只对第一个元素有效。你能帮我吗?我附上了代码的必要部分: MainWindow.xaml <ListView Name="EmployeeListView" HorizontalAlignment=
<ListView Name="EmployeeListView" HorizontalAlignment="Left" Height="160" Margin="0,153,0,0" VerticalAlignment="Top" Width="755" Grid.Row="1" ItemsSource="{Binding FilteredCollection, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedEmployee, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedIndex="{Binding SelectedIndex}" IsSynchronizedWithCurrentItem="True">
<ListView.View>
<GridView>
<GridViewColumn Header="EmployeeName" Width="150" DisplayMemberBinding="{Binding EmployeeName}" />
<GridViewColumn Header="EmployeeID" Width="150" DisplayMemberBinding="{Binding EmployeeID}" />
<GridViewColumn Header="EmployeeSalary" Width="150" DisplayMemberBinding="{Binding EmployeeSalary}" />
<GridViewColumn Header="EmployeeDesigner" Width="150" DisplayMemberBinding="{Binding EmployeeDesigner}" />
<GridViewColumn Header="EmployeeEmailID" Width="150" DisplayMemberBinding="{Binding EmployeeEmailID}" />
</GridView>
</ListView.View>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Employee.cs
public IEnumerable<Employee> SelectedEmployees
{
get
{
selectedEmployees = Employees.Where(o => o.IsSelected).ToList();
return selectedEmployees;
}
set
{
selectedEmployees = value;
OnPropertyChanged("SelectedEmployees");
}
}
public bool IsSelected
{
get
{
//Application.Current.Dispatcher.BeginInvoke(new Action(() => MessageBox.Show("SELE")));
return isSelected;
}
set
{
isSelected = value;
OnPropertyChanged("IsSelected");
}
}
public ObservableCollection<Employee> Employees
{
get
{
return employees;
}
set
{
employees = value;
OnPropertyChanged("Employees");
}
}
public ICollectionView FilteredCollection
{
get
{
return filteredCollection;
}
set
{
filteredCollection = value;
OnPropertyChanged("FilteredCollection");
}
}
public Employee SelectedEmployee
{
get
{
//Application.Current.Dispatcher.BeginInvoke(new Action(() => MessageBox.Show(selectedEmployee.SelectedEmployee.ToString())));
return selectedEmployee;
}
set
{
selectedEmployee = value;
if (selectedEmployee == null)
{
ModeOfExecuting = "Searching / Adding Mode";
OnPropertyChanged("SelectedEmployee");
OnPropertyChanged("ModeOfExecuting");
OnPropertyChanged("FilteredCollection");
}
if (selectedEmployee != null)
{
//MessageBox.Show(Employees[SelectedIndex.GetValueOrDefault()].EmployeeName.ToString());
//List<Employee> FilteredCollectionList = FilteredCollection.Cast<Employee>().ToList();
//MessageBox.Show(FilteredCollectionList[0].EmployeeName);
if (selectedEmployee.EmployeeName != string.Empty)
{
RememberValueEmployeeName = selectedEmployee.EmployeeName;
DynamicSearchEmployeeName = RememberValueEmployeeName;
}
if (selectedEmployee.EmployeeID != null)
{
RememberValueEmployeeID = selectedEmployee.EmployeeID;
DynamicSearchEmployeeID = RememberValueEmployeeID;
}
if (selectedEmployee.EmployeeSalary != null)
{
RememberValueEmployeeSalary = selectedEmployee.EmployeeSalary;
DynamicSearchEmployeeSalary = RememberValueEmployeeSalary.ToString();
}
if (selectedEmployee.EmployeeDesigner != string.Empty)
{
RememberValueEmployeeDesigner = selectedEmployee.EmployeeDesigner;
DynamicSearchEmployeeDesigner = RememberValueEmployeeDesigner;
}
if (selectedEmployee.EmployeeEmailID != string.Empty)
{
RememberValueEmployeeEmailID = selectedEmployee.EmployeeEmailID;
DynamicSearchEmployeeEmailID = RememberValueEmployeeEmailID;
}
ModeOfExecuting = "Editing Mode";
OnPropertyChanged("SelectedEmployee");
}
OnPropertyChanged("SelectedEmployee");
}
}
我玩了一会儿,想出了这个解决方案。 我的目标是使绑定的使用成为可能。 如果你发现任何错误,请告诉我 我创建了一个附加的行为和相应的附加属性
public static class LastSelectedItemBehavior
{
public static readonly DependencyProperty ExposeLastSelectedItemProperty =
DependencyProperty.RegisterAttached("ExposeLastSelectedItem", typeof(bool), typeof(LastSelectedItemBehavior),
new PropertyMetadata(false, ExposeLastSelectedItemChanged));
public static bool GetExposeLastSelectedItem(ListBox element)
{
return (bool)element.GetValue(ExposeLastSelectedItemProperty);
}
public static void SetExposeLastSelectedItem(ListBox element, bool value)
{
element.SetValue(ExposeLastSelectedItemProperty, value);
}
private static void ExposeLastSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is ListBox listBox && e.NewValue is bool boolValue)
{
if (boolValue)
{
listBox.SelectionChanged += ListBox_SelectedItemsChanged;
}
else
{
listBox.SelectionChanged -= ListBox_SelectedItemsChanged;
}
}
}
private static void ListBox_SelectedItemsChanged(object sender, SelectionChangedEventArgs e)
{
var listBox = (ListBox) sender;
listBox.SetValue(LastSelectedItemPropertyKey, listBox.SelectedItems.Count > 0 ? listBox.SelectedItems[listBox.SelectedItems.Count - 1] : default(object));
}
private static readonly DependencyPropertyKey LastSelectedItemPropertyKey =
DependencyProperty.RegisterAttachedReadOnly(
"LastSelectedItem",
typeof(object),
typeof(LastSelectedItemBehavior),
new PropertyMetadata(default(object)));
public static readonly DependencyProperty LastSelectedItemProperty = LastSelectedItemPropertyKey.DependencyProperty;
public static object GetLastSelectedItem(ListBox element)
{
return element.GetValue(LastSelectedItemProperty);
}
}
在ListView上,必须设置ExposeLastSelectedItem
然后你可以像这样绑起来
<ContentControl Content="{Binding ElementName=listView, Path=(local:LastSelectedItemBehavior.LastSelectedItem)}" />
编辑:
MVVM友好的解决方案,使用来自
我自己解决了我的问题。我附加了部分添加的代码。 在此之前,您必须执行以下步骤。有必要处理交互触发器。解决方案:当我选择项目时,我将其索引添加到列表中。在我选择的选定项上设置SelectedItem属性。然后,对于这些索引位于列表中的员工,IsSelected属性设置为true。我使用HashSet来避免重复的值:当我选择列表中的第二项时,第一个选定项的索引再次添加到列表中。请随意评论: XAML文件添加到ListView控件:
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectionChanged}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
你的目标是什么:Winforms、WPF、ASP。。?您应该始终正确标记您的问题,以便人们可以在问题页面上看到它!我总是把我的问题贴上标签,就像现在。。。没有人对此有异议。你是第一个。。。WPF@AdrianPrzemysławDrozdowski你试过使用SelectedItems吗?该列表中的顺序应为选择顺序,但批量选择除外,在批量选择中,它们会像显示一样被添加。在Listview中,无法使用默认的SelectedItems属性:@AdrianPrzemysławDrozdowski您是否使用自定义Listview?因为ListView肯定已经选择了Editems,我非常感谢您的解决方案,但它不是用纯MVVM体系结构编写的:@AdrianPrzemysławDrozdowski我对MVVM模式比较陌生,但我认为该解决方案将与MVVM完全兼容。你们能解释一下为什么不是这样吗?我也是MVVM模式的新手:但MVVM的存在是和UI分离的逻辑。不幸的是,您在代码隐藏中使用了视图控件。您应该始终绑定属性以查看控件的属性。@AdrianPrzemysławDrozdowski感谢您的解释。通过一些额外的研究,我想我现在明白了。我添加了另一个应该对MVVM友好的解决方案。很抱歉很长时间没有响应,但我必须阅读有关依赖关系、附加属性和行为的信息:现在我正在尝试将您的解决方案用于我的应用程序。
<ListView x:Name="listView" local:LastSelectedItemBehavior.ExposeLastSelectedItem="True">
<local:DataPiping.DataPipes>
<local:DataPipeCollection>
<local:DataPipe
Source="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListView}}, Path=(local:LastSelectedItemBehavior.LastSelectedItem)}"
Target="{Binding Path=LastSelectedItem, Mode=OneWayToSource}"/>
</local:DataPipeCollection>
</local:DataPiping.DataPipes>
</ListView>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectionChanged}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
public HashSet<int> IndexesOfSelectedEmployees
{
get
{
return indexesOfSelectedEmployees;
}
set
{
indexesOfSelectedEmployees = value;
OnPropertyChanged("IndexesOfSelectedEmployees");
}
}
public void OnSelectionChanged(object parameter)
{
if(SelectedEmployee == null)
{
IndexesOfSelectedEmployees.Clear();
}
if(SelectedEmployee != null)
{
foreach (Employee item in Employees)
{
if (item.IsSelected == true)
{
IndexesOfSelectedEmployees.Add(SelectedIndex.GetValueOrDefault());
}
}
foreach (int itemIndexesOfSelectedEmployees in IndexesOfSelectedEmployees)
{
foreach (Employee itemEmployees in Employees)
{
if (itemIndexesOfSelectedEmployees == Employees.IndexOf(itemEmployees))
{
itemEmployees.IsSelected = true;
}
}
}
}