2009-07-01 27 views
17

Oh, hombre. Estoy sintiendo el dolor de WPF esta semana. Entonces, para mi próximo truco, ahora no puedo descubrir cómo seleccionar un elemento programáticamente en un ListView.WPF ListView Seleccionar programáticamente elemento

Estoy intentando usar el ItemContainerGenerator de listview, pero parece que no funciona. Por ejemplo, obj es nula después de la siguiente operación:

//VariableList is derived from BindingList 
m_VariableList = getVariableList(); 
lstVariable_Selected.ItemsSource = m_VariableList; 
var obj = 
    lstVariable_Selected.ItemContainerGenerator.ContainerFromItem(m_VariableList[0]); 

He tratado (basado en las sugerencias que se ven aquí y en otros lugares) para utilizar el evento StatusChanged del ItemContainerGenerator, pero fue en vano. El evento nunca se dispara. Por ejemplo:

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

El quid de todo esto es que simplemente quiero preseleccionar algunos de los artículos en mi ListView.

Con el interés de no dejar nada, el ListView utiliza algunas plantillas y funcionalidad de arrastrar/soltar, por lo que estoy incluyendo el XAML aquí. Esencialmente, esta plantilla hace que cada elemento sea un cuadro de texto con texto, y cuando se selecciona un elemento, se marca la casilla de verificación. Y cada artículo también se hace un poco por debajo de ella glifo para insertar nuevos artículos (y todo esto funciona bien):

<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"/> 

Entonces, ¿qué me falta? ¿Cómo selecciono programáticamente uno o más de los elementos en ListView?

Muchas gracias por su tiempo.

Respuesta

30

Enlaza la propiedad IsSelected del ListViewItem a una propiedad en tu modelo. Entonces, solo necesita trabajar con su modelo en lugar de preocuparse por las complejidades de la interfaz de usuario, que incluye riesgos potenciales en torno a la virtualización de contenedores.

Por ejemplo:

<ListView> 
    <ListView.ItemContainerStyle> 
     <Style TargetType="ListViewItem"> 
      <Setter Property="IsSelected" Value="{Binding IsGroovy}"/> 
     </Style> 
    </ListView.ItemContainerStyle> 
</ListView> 

Ahora, sólo el trabajo con la propiedad de su modelo IsGroovy para seleccionar/anular la selección de elementos en el ListView.

+2

Pero por supuesto. El enlace de datos. ¿No todos los problemas en WPF se reducen en algún momento a la vinculación de datos? Gracias, Kent. –

+0

¡Esta es una solución realmente genial, felicitaciones! –

+4

Solo mencione: esta solución no funciona en la aplicación Windows Store. En su lugar, debe establecer el enlace en el código, así: http: //social.msdn.microsoft.com/Forums/windowsapps/en-US/9a0adf35-fdad-4419-9a34-a9dac052a2e3/listviewitemisselected-data-binding-in -style-setter-is-not-working? forum = winappswithcsharp – SimonFisher

4

Aquí estaría mi mejor estimación, que sería un método mucho más simple para la selección. Ya que no estoy seguro de lo que está seleccionando en, aquí hay un ejemplo genérico:

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

Lo que yo estoy acostumbrado a ver es un SelectedItem configurable, pero veo que no se puede establecer o añadir a esto, pero espero que este método funcione como un reemplazo.

3

Donde 'this' es la instancia de ListView. Esto no solo cambiará la selección, sino que también establecerá el foco en el elemento recién seleccionado.

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(); 
    } 
    } 
Cuestiones relacionadas