WPF - ListView с кнопкой - PullRequest
8 голосов
/ 07 февраля 2011

У меня есть шаблон списка, а один столбец - кнопка. Мне нужно выбрать пункт, когда я нажимаю на эту кнопку. Как я могу это сделать ??

Ответы [ 2 ]

13 голосов
/ 07 февраля 2011

Чтобы поймать выбранный элемент ListView внутри события нажатия кнопки, вы можете использовать шаблон MVVM.В моем ListView, в XAML, я связываю ItemsSource и SelectedItem с классом ViewModel.Я также привязываю свою кнопку Command в шаблоне к RunCommand во ViewModel.

Сложная часть заключается в получении правильной привязки из шаблона к активному DataContext.

Как только вы это сделаете, вы можете захватить SelectedCustomer внутри RunCommand, который выполняется при нажатии кнопки.

Я включил часть кода, чтобы помочь вам начать.Вы можете найти реализации ViewModelBase и DelegateCommand через Google.

Вот 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>

Вот ViewModel:

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

Здесь я ссылаюсьв ViewModel для просмотра:

public partial class MainView : Window
{
  public MainView()
  {
     InitializeComponent();
     DataContext = new ViewModels.MainViewModel();
  }
}
3 голосов
/ 31 октября 2014

Пример с обычным событием клика в коде:

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

Код:

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
}

Примечание. Несмотря на то, что я, безусловно, ценю MVVM, я пришел к выводу, что при переходе к действиям и обмену сообщениями между формой и виртуальной машиной возникает довольно крутой наклон димминговой отдачи, поэтому я использую его только в случаях отношения между виртуальными машинами или большими единичными виртуальными машинами. Для приложений, ориентированных на данные в стиле CRUD, я предпочитаю обрабатывать действия и ретрансляцию сообщений с помощью кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...