2011-02-07 90 views
8

我有一个列表视图模板,一列是一个按钮。当我点击这个按钮时,我需要选择的项目。我怎么能做到这一点?WPF - 按钮列表视图

+1

你的意思是你想得到当前选择的项目,还是你想选择按钮所在的项目? – Botz3000 2011-02-07 12:03:49

回答

13

要使按钮按下的事件内选定的ListView项目成熟,您可以利用MVVM模式。在我的ListView中,在XAML中,我将ItemsSource和SelectedItem绑定到ViewModel类。我还将模板中的按钮Command绑定到ViewModel中的RunCommand。

棘手的部分是从模板获取正确的绑定到活动的DataContext。

一旦你这样做,你可以捕获RunCommand中的SelectedCustomer,当按钮被按下时, 被执行。

我已经包含了一些帮助您入门的代码。 您可以通过Google找到ViewModelBase和DelegateCommand的实现。

这里是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> 

这里是视图模型:

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

这里是我在视图模型链接到检视:用

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

实施例在后面的代码中定期点击事件:

<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,我已经开始接受有dimminishing回报相当陡峭的斜坡,一旦你跨入形式之间的行动和通讯虚拟机,所以我只在虚拟机或大型单一虚拟机之间存在复杂关系的情况下才使用它。对于CRUD风格的以数据为中心的应用程序,我倾向于使用后面的代码来处理操作和消息中继。