2011-02-07 26 views
8

私はリストビューテンプレートを持ち、1列はボタンです。このボタンをクリックすると、選択したアイテムが必要になります。どのように私はこれを行うことができますか?WPF - ボタン付きリストビュー

+1

現在選択されているアイテムを取得するか、ボタンが含まれているアイテムを選択しますか? – Botz3000

答えて

13

ボタンを押したイベント内で選択したListViewアイテムを成熟させるには、MVVMパターンを利用できます。私のリストビューでは、XAMLでは、ItemsSourceとSelectedItemをViewModelクラスにバインドします。私はまた、テンプレートのボタンコマンドを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> 

はViewModelにある:私はビューに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; 
    } 
    } 
} 

は次のとおりです。と

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リターンのかなり急な斜面があることを受け入れるようになってきましたし、 VMのため、私は、VMや大きな単一のVM間の複雑な関係の場合にのみ使用します。 CRUDスタイルのデータ中心のアプリケーションでは、コードの背後にあるアクションとメッセージリレーを処理する方が好きです。

関連する問題