Выберите элемент программно в WPF ListView
Я не могу понять, как программно выбрать элемент в ListView.
Я пытаюсь использовать ItemContainerGenerator в listview, но он просто не работает. Например, obj имеет значение null после следующей операции:
//VariableList is derived from BindingList
m_VariableList = getVariableList();
lstVariable_Selected.ItemsSource = m_VariableList;
var obj =
lstVariable_Selected.ItemContainerGenerator.ContainerFromItem(m_VariableList[0]);
Я пытался (основываясь на предложениях, замеченных здесь и в других местах) использовать событие StatusChanged ItemContainerGenerator, но безрезультатно. Событие никогда не начинается. Например:
m_VariableList = getVariableList();
lstVariable_Selected.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);
lstVariable_Selected.ItemsSource = m_VariableList;
...
void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
//This code never gets called
var obj = lstVariable_Selected.ItemContainerGenerator.ContainerFromItem(m_VariableList[0]);
}
Суть всего этого в том, что я просто хочу предварительно выбрать несколько элементов в моем ListView.
Чтобы ничего не пропустить, ListView использует некоторые шаблоны и функцию перетаскивания, поэтому я включаю XAML здесь. По сути, этот шаблон делает каждый элемент текстовым полем с некоторым текстом - и когда любой элемент выбран, флажок установлен. И каждый элемент также получает небольшой глиф под ним, чтобы вставить новые элементы (и это все работает отлично):
<DataTemplate x:Key="ItemDataTemplate_Variable">
<StackPanel>
<CheckBox x:Name="checkbox"
Content="{Binding Path=ListBoxDisplayName}"
IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}" />
<Image ToolTip="Insert Custom Variable" Source="..\..\Resources\Arrow_Right.gif"
HorizontalAlignment="Left"
MouseLeftButtonDown="OnInsertCustomVariable"
Cursor="Hand" Margin="1, 0, 0, 2" Uid="{Binding Path=CmiOrder}" />
</StackPanel>
</DataTemplate>
...
<ListView Name="lstVariable_All" MinWidth="300" Margin="5"
SelectionMode="Multiple"
ItemTemplate="{StaticResource ItemDataTemplate_Variable}"
SelectionChanged="lstVariable_All_SelectionChanged"
wpfui:DragDropHelper.IsDropTarget="True"
wpfui:DragDropHelper.IsDragSource="True"
wpfui:DragDropHelper.DragDropTemplate="{StaticResource ItemDataTemplate_Variable}"
wpfui:DragDropHelper.ItemDropped="OnItemDropped"/>
Так чего мне не хватает? Как программно выбрать один или несколько элементов в ListView?
3 ответа
Привязать IsSelected
собственность ListViewItem
на недвижимость по вашей модели. Тогда вам нужно только работать с вашей моделью, а не беспокоиться о тонкостях пользовательского интерфейса, который включает в себя потенциальные риски, связанные с виртуализацией контейнера.
Например:
<ListView>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsSelected" Value="{Binding IsGroovy}"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Теперь просто работайте с вашей моделью IsGroovy
свойство для выбора / отмены выбора элементов в ListView
,
Где this это экземпляр ListView. Это не только изменит выбор, но и установит фокус на вновь выбранном элементе.
private void MoveSelection(int level)
{
var newIndex = this.SelectedIndex + level;
if (newIndex >= 0 && newIndex < this.Items.Count)
{
this.SelectedItem = this.Items[newIndex];
this.UpdateLayout();
((ListViewItem)this.ItemContainerGenerator.ContainerFromIndex(newIndex)).Focus();
}
}
Вот моя лучшая догадка, которая была бы намного более простым методом для выбора. Поскольку я не уверен, что вы выбираете, вот общий пример:
var indices = new List<int>();
for(int i = 0; i < lstVariable_All.Items.Count; i++)
{
// If this item meets our selection criteria
if( lstVariable_All.Items[i].Text.Contains("foo") )
indices.Add(i);
}
// Reset the selection and add the new items.
lstVariable_All.SelectedIndices.Clear();
foreach(int index in indices)
{
lstVariable_All.SelectedIndices.Add(index);
}
То, что я привык видеть, это настраиваемый SelectedItem, но я вижу, что вы не можете установить или добавить к этому, но, надеюсь, этот метод работает как замена.
Если вы не работаете с привязками, это также может быть решением, просто найдите элементы в источнике и добавьте их в свойство SelectedItems вашего списка:
lstRoomLights.ItemsSource = RoomLights;
var selectedItems = RoomLights.Where(rl => rl.Name.Contains("foo")).ToList();
selectedItems.ForEach(i => lstRoomLights.SelectedItems.Add(i));