Как получить последний элемент из списка, когда элементы выбраны - PullRequest
0 голосов
/ 03 декабря 2018

У меня небольшая проблема с множественным выбором и свойством SelectedItem.Мое приложение работает следующим образом: когда я нажимаю на запись в Listview, данные из этой записи отображаются в текстовых полях.А теперь вот моя проблема.Я хочу добиться функциональности, например: Когда я нажимаю на запись один за другим, я хочу отобразить данные последнего выбранного элемента.К сожалению, SelectedItem работает только для первого элемента.Не могли бы вы помочь мне?Я приложил необходимую часть кода:

enter image description here

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

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Я решил свою проблему самостоятельно.Я приложил части добавленного кода.Прежде всего вы должны сделать шаги из этой статьи .Необходимо обрабатывать триггеры взаимодействия.Решение: Когда я выбираю элемент, я добавляю его индекс в список.Свойство SelectedItem устанавливается на выбранный элемент, который я выбрал.Затем свойство IsSelected устанавливается равным true для этих сотрудников, индексы которых находятся в списке.Я использую HashSet, чтобы избежать дублирования значений: когда я выбирал второй элемент в списке, индекс первого выбранного элемента добавлялся в список еще раз.Не стесняйтесь комментировать:)

enter image description here

XAML-файл (добавить в элемент управления ListView):

            <i:Interaction.Triggers>
                <i:EventTrigger EventName="SelectionChanged">
                    <i:InvokeCommandAction Command="{Binding SelectionChanged}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>

Employee.cs file

        public HashSet<int> IndexesOfSelectedEmployees
        {
            get
            {
                return indexesOfSelectedEmployees;
            }
            set
            {
                indexesOfSelectedEmployees = value;
                OnPropertyChanged("IndexesOfSelectedEmployees");
            }
        }

Файл EmployeeViewModel.cs:

          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;
                        }
                    }
                }
          }
0 голосов
/ 03 декабря 2018

Я немного поиграл и нашел это решение.
Моя цель состояла в том, чтобы сделать возможным использование Binding.
Если вы обнаружите какую-либо ошибку, дайте мне знать.

Iсоздал прикрепленное поведение и соответствующее прикрепленное свойство

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

<ListView x:Name="listView" local:LastSelectedItemBehavior.ExposeLastSelectedItem="True" />

И тогда вы можете связать вот так

<ContentControl Content="{Binding ElementName=listView, Path=(local:LastSelectedItemBehavior.LastSelectedItem)}" />

Редактировать:

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...