C# 如何在多选项目时从Listview获取最后一个项目

C# 如何在多选项目时从Listview获取最后一个项目,c#,wpf,mvvm,multi-select,selecteditem,C#,Wpf,Mvvm,Multi Select,Selecteditem,我对multiselect和SelectedItem属性有点问题。我的应用程序的工作方式如下:当我在Listview中单击一条记录时,该记录中的数据显示在文本框中。现在是我的问题。我想实现这样的功能:当我一个接一个地点击一条记录时,我想显示上一个选中项目的数据。不幸的是,SelectedItem只对第一个元素有效。你能帮我吗?我附上了代码的必要部分: MainWindow.xaml <ListView Name="EmployeeListView" HorizontalAlignment=

我对multiselect和SelectedItem属性有点问题。我的应用程序的工作方式如下:当我在Listview中单击一条记录时,该记录中的数据显示在文本框中。现在是我的问题。我想实现这样的功能:当我一个接一个地点击一条记录时,我想显示上一个选中项目的数据。不幸的是,SelectedItem只对第一个元素有效。你能帮我吗?我附上了代码的必要部分:

MainWindow.xaml

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