2011-02-07 16 views
8

tengo una plantilla listview y una columna es un botón. Necesito el artículo seleccionado cuando hago clic en este botón. Como puedo hacer esto ??WPF - Vista de lista con el botón

+1

¿Quiere decir que quiere obtener el elemento seleccionado actualmente o desea seleccionar el elemento donde está el botón? – Botz3000

Respuesta

13

Para capturar el elemento ListView seleccionado dentro de un evento presionado por botón, puede aprovechar el patrón MVVM. En mi ListView, en el XAML, vinculo el ItemsSource y SelectedItem a una clase ViewModel. También ato mi botón Comando en la plantilla a RunCommand en ViewModel.

La parte difícil es obtener el enlace correcto de la plantilla al DataContext activo.

Una vez hecho esto, puede capturar el Cliente Seleccionado dentro del RunCommand que se ejecuta cuando se presiona el botón.

He incluido parte del código para ayudarlo a comenzar. Puede encontrar implementaciones de ViewModelBase y DelegateCommand a través de Google.

Aquí es el XAML:

<Window x:Class="ListViewScrollPosition.Views.MainView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Main Window" Height="400" Width="400"> 
    <Grid> 
    <ListView ItemsSource="{Binding Path=Customers}" 
       SelectedItem="{Binding Path=SelectedCustomer}" 
       Width="Auto"> 
     <ListView.View> 
      <GridView> 
       <GridViewColumn Header="First Name"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <StackPanel Margin="6,2,6,2"> 
           <TextBlock Text="{Binding FirstName}"/> 
          </StackPanel> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn Header="Last Name"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <StackPanel Margin="6,2,6,2"> 
           <TextBlock Text="{Binding LastName}"/> 
          </StackPanel> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn Header="Address"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <StackPanel Margin="6,2,6,2"> 
           <Button Content="Address" 
            Command="{Binding 
            Path=DataContext.RunCommand, 
            RelativeSource= 
            {RelativeSource FindAncestor, 
            AncestorType={x:Type ItemsControl}}}"/> 
          </StackPanel> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
      </GridView> 
     </ListView.View> 
    </ListView> 
    </Grid> 
</Window> 

Aquí es el modelo de vista:

using System.Collections.ObjectModel; 
using System.Windows.Input; 
using ListViewScrollPosition.Commands; 
using ListViewScrollPosition.Models; 

namespace ListViewScrollPosition.ViewModels 
{ 
    public class MainViewModel : ViewModelBase 
    { 
    public ICommand RunCommand { get; private set; } 

    public MainViewModel() 
    { 
     RunCommand = new DelegateCommand<object>(OnRunCommand, CanRunCommand); 
     _customers = Customer.GetSampleCustomerList(); 
     _selectedCustomer = _customers[0]; 
    } 

    private ObservableCollection<Customer> _customers = 
        new ObservableCollection<Customer>(); 
    public ObservableCollection<Customer> Customers 
    { 
     get 
     { 
     return _customers; 
     } 
    } 

    private Customer _selectedCustomer; 
    public Customer SelectedCustomer 
    { 
     get 
     { 
     return _selectedCustomer; 
     } 
     set 
     { 
     _selectedCustomer = value; 
     OnPropertyChanged("SelectedCustomer"); 
     } 
    } 

    private void OnRunCommand(object obj) 
    { 
     // use the SelectedCustomer object here... 
    } 

    private bool CanRunCommand(object obj) 
    { 
     return true; 
    } 
    } 
} 

Aquí es donde enlazo en el modelo de vista a la vista:

public partial class MainView : Window 
{ 
    public MainView() 
    { 
    InitializeComponent(); 
    DataContext = new ViewModels.MainViewModel(); 
    } 
} 
3

Ejemplo con una evento de clic regular en el código detrás:

<ListView Height="167.96" VerticalAlignment="Top" ItemsSource="{Binding FulfillmentSchedules}" SelectedItem="{Binding SelectedFulfillmentSchedule}"> 
    <ListView.View> 
    <GridView> 
     <GridViewColumn Header="Request"> 
     <GridViewColumn.CellTemplate> 
      <DataTemplate> 
      <TextBlock> 
       <TextBlock.Text> 
       <MultiBinding StringFormat="{}{0}-{1}-{2}"> 
        <Binding Path="Template.ProjectNumber" /> 
        <Binding Path="Template.JobNumber" /> 
        <Binding Path="Template.RequestId" /> 
       </MultiBinding> 
       </TextBlock.Text> 
      </TextBlock> 
      </DataTemplate> 
     </GridViewColumn.CellTemplate> 

     </GridViewColumn> 
     <GridViewColumn Header="Template" DisplayMemberBinding="{Binding Template.Name}"/> 
     <GridViewColumn Header="Start Date" DisplayMemberBinding="{Binding StartDate}"/> 
     <GridViewColumn Header="Records" DisplayMemberBinding="{Binding Parameters.Records}"/> 
     <GridViewColumn> 
     <GridViewColumn.CellTemplate> 
      <DataTemplate> 
      <Button Name="BtnYourButton" Content="Your Button" Click="BtnYourButton_Click" /> 
      </DataTemplate> 

     </GridViewColumn.CellTemplate> 

     </GridViewColumn> 
    </GridView> 
    </ListView.View> 
</ListView> 

Código atrás:

private void BtnYourButton_Click(object sender, RoutedEventArgs e) 
{ 
    var boundData= (YourBoundDataType)((Button)sender).DataContext; 
    //do what you need to do here, including calling other methods on your VM 
} 

Nota: Mientras Ciertamente aprecio MVVM, he llegado a aceptar que hay una pendiente bastante empinada de dimminishing vuelve una vez que cruce en acciones y la mensajería entre la forma y la máquina virtual, por lo que la utilizo solo en casos de relaciones complejas entre máquinas virtuales o grandes máquinas virtuales singulares. Para aplicaciones centradas en datos de estilo CRUD, prefiero manejar acciones y retransmisión de mensajes con el código subyacente.

Cuestiones relacionadas