【问题标题】:WPF - Listview with buttonWPF - 带有按钮的列表视图
【发布时间】:2011-06-22 16:55:42
【问题描述】:

我有一个列表视图模板,其中一列是一个按钮。单击此按钮时,我需要选定的项目。我该怎么做??

【问题讨论】:

  • 你的意思是要获取当前选中的item还是要选中button所在的item?

标签: wpf listview button


【解决方案1】:

要在按钮按下事件中捕获选定的 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;
    }
  }
}

这里是我将 ViewModel 链接到 View 的地方:

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

【讨论】:

    【解决方案2】:

    后面代码中带有常规点击事件的示例:

    <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,但我已经开始接受,一旦您进入表单和 VM 之间的操作和消息传递,就会出现相当陡峭的收益递减斜率,因此我只在复杂的情况下使用它虚拟机或大型单一虚拟机之间的关系。对于 CRUD 风格的以数据为中心的应用程序,我更喜欢使用背后的代码来处理动作和消息中继。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 2011-02-11
      • 2012-10-16
      • 1970-01-01
      相关资源
      最近更新 更多