Cómo asociar el botón a ListView.SelectedItem

Tengo un ListView ItemsSource vinculado a un ObservableCollection. Agregué una propiedad a través de MVVM para rastrear ListView.SelectedItem. Se agregó un botón a mi ListView (a través de GridViewColumn.CellTemplate) para crear un comando de botón que muestra datos sobre cada objeto en mi ObservableCollection. Entonces, la lista de objetos en mi ObservableCollection (ListView columna 1) se muestra en ListView con un botón correspondiente (ListView columna 2).

¡El Código funciona muy bien! El único problema: el usuario debe hacer clic en la fila ListView antes de hacer clic en el botón correspondiente en la lista. (Recibo una excepción de referencia nula en mi propiedad "SelectedFromQueue" si el usuario hace clic en el botón sin hacer clic primero en la fila ListView).

Me gustaría agregar código que establece la propiedad ListView.SelectedItem cuando se hace clic en un botón. Por lo tanto, si el usuario hace clic en un botón, el código debe actualizar el enlace de la propiedad ListView.SelectedItem antes de que se ejecute el comando MVVM asociado.

¿Alguien tiene algún código de ejemplo para esto? Gracias por tu ayuda.

Mi XAML:

<UserControl xmlns:local="clr-namespace:MyApp"
             x:Class="MyApp.QueueObjectList"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" Height="290" Width="320">

    <Grid Width="319">
        <GroupBox Header="Queue Class List" HorizontalAlignment="Left" Width="319" BorderBrush="Black" BorderThickness="2">
            <ListView ItemsSource="{Binding Path=QueueList}" Name="QueueListView">
                <ListView.SelectedItem>
                    <Binding Path="SelectedFromQueue" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
                    </Binding>               
                </ListView.SelectedItem>
                <ListView.View>
                    <GridView>
                        <GridViewColumn Width="140" Header="Queue Name" DisplayMemberBinding="{Binding Name}" />
                        <GridViewColumn Width="179" Header="Property Information">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <Button Content="Get Property Info" Command="{Binding Path=GetQueueObjProperties}"
                                        DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType=ListView}}" />                      
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                    </GridView>
                </ListView.View>
            </ListView>
        </GroupBox>
    </Grid>
</UserControl>

Mi código MainWindowViewModel C #:

private ObservableCollection<Queue> _QueueList;
private Queue _selectedFromQueue;

public ObservableCollection<Queue> QueueList
{
    get { return _QueueList; }
    set
    {
        _QueueList = value;
        RaisePropertyChanged("QueueList");
    }
}

public Queue SelectedFromQueue
{
    get { return _selectedFromQueue; }
    set
    {
        _selectedFromQueue= value;
        RaisePropertyChanged("SelectedFromQueue");
    }
}

// Constructor
public MainWindowViewModel()
{
    QueueList = new ObservableCollection<Queue>();
    _selectedFromQueue= null;
}

public ICommand GetQueueObjProperties
{
    get { return new RelayCommand(GetQueueProperties, CanGetQueueProperties); }
}

private bool CanGetQueueProperties()
{
    if (_QueueList.Count > 0)
    {
        return true;
    }
    return false;
}

private void GetQueueProperties()
{
    if (CanGetQueueProperties())
    {
        ResponseMessage.Add("Queue name: " +SelectedFromQueue.Name);
    }
}

Actualización: ¡Gracias sll!

Agregué lo siguiente a mi código XAML:

            <ListView.Resources>
                <Style TargetType="{x:Type ListViewItem}">
                    <EventSetter Event="PreviewGotKeyboardFocus" Handler="SelectCurrentItem"/>
                </Style>
            </ListView.Resources>

Agregué el siguiente método c # para codificar detrás:

        protected void SelectCurrentItem(Object sender, KeyboardFocusChangedEventArgs e)
        {
            ListViewItem item = (ListViewItem)sender;
            item.IsSelected = true;
        }

¡Funciona genial! ¡Gracias de nuevo por la referencia sll!

preguntado el 08 de noviembre de 11 a las 15:11

He preguntado lo mismo antes, consulte esta pregunta, tal vez la solución proporcionada por Rachel lo ayude: WPF: Trigger SelectedIndex cambió al hacer clic en cualquier control dentro de un área ListBoxItem -

1 Respuestas

No estoy seguro de qué GetQueueProperties lo hace, pero parece que usas SelectedFromQueue para saber en qué elemento ejecutar su lógica y la selección en la GUI es secundaria.

Si ese es el caso, no use SelectedFromQueue pero agregue esto al Button:

CommandParameter="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType=ListViewItem}}"

Esto te dará una Queue objeto asociado con la fila del botón pulsado como e.Parameter in SelectedFromQueue.

Si do Necesita configurar el elemento seleccionado para la GUI, al comienzo de SelectedFromQueue añadir:

SelectedFromQueue = (e.Parameter is Queue) ? e.Parameter : null

respondido 08 nov., 11:23

Gracias XAMeLi Tenga en cuenta el nuevo código que agregué a esta publicación. Agregué un nuevo ListView.Resource para acceder al EventSetter para ListView. El controlador de eventos se vincula a un nuevo método c # en el código subyacente. El método SelectCurrentItem de c # establece la propiedad "IsSelected" en true cuando el usuario pasa el mouse sobre cualquier fila en ListView. Ahora, mis usuarios pueden simplemente hacer clic en un botón asociado a la fila y acceder al objeto correspondiente desde ObservableCollection. - EnLaCucha

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.