2011-02-07 37 views
8

tôi có một mẫu listview và một cột là một nút. Tôi cần mục đã chọn khi tôi nhấp vào nút này. Làm thế nào tôi có thể làm điều này ??WPF - Listview với nút

+1

Bạn có muốn chọn mục hiện đang được chọn hoặc bạn có muốn chọn mục có nút đó không? – Botz3000

Trả lời

13

Để hạn chế mục ListView đã chọn bên trong sự kiện nhấn nút, bạn có thể tận dụng mẫu MVVM. Trong ListView của tôi, trong XAML, tôi ràng buộc ItemsSource và SelectedItem với một lớp ViewModel. Tôi cũng liên kết nút Command của tôi trong mẫu để RunCommand trong ViewModel.

Phần khó khăn là nhận được ràng buộc đúng từ mẫu đến DataContext đang hoạt động.

Khi bạn thực hiện việc này, bạn có thể chụp SelectedCustomer bên trong RunCommand rằng được thực hiện khi nút được nhấn.

Tôi đã bao gồm một số mã để giúp bạn bắt đầu. Bạn có thể tìm các triển khai của ViewModelBase và DelegateCommand thông qua Google.

Đây là 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> 

Đây là 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; 
    } 
    } 
} 

Đây là nơi tôi liên kết trong ViewModel để xem:

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

Ví dụ với một sự kiện nhấp thường xuyên trong mã phía sau:

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

Mã đằng sau:

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 
} 

Lưu ý: Trong khi tôi chắc chắn đánh giá cao MVVM, tôi đã đến để chấp nhận rằng có một độ dốc khá dốc của dimminishing lợi nhuận một khi bạn vượt qua thành hành động và nhắn tin giữa hình thức và VM, vì vậy tôi chỉ sử dụng nó trong trường hợp các mối quan hệ phức tạp giữa các máy ảo hoặc các máy ảo số ít lớn. Đối với các ứng dụng tập trung vào dữ liệu kiểu CRUD, tôi thích xử lý các hành động và chuyển tiếp tin nhắn với mã phía sau.