简体   繁体   English

如何将带有contextMenu的WPF ListView绑定到viewModel

[英]How to bind a WPF ListView with contextMenu to viewModel

I'm trying to bind a listview to List<OrderPaymentVm> OrderPayments with a right click contextmenu to get the PaymentTransactionId . 我正在尝试通过右键单击contextmenu将List<OrderPaymentVm> OrderPayments绑定到List<OrderPaymentVm> OrderPayments以获取PaymentTransactionId

I have the following property in my forms view model 我的表单视图模型中具有以下属性

  public List<OrderPaymentVm> OrderPayments
  {
     get
     {
        return _orderPayments;
     }

     private set
     {
        _orderPayments = value;
        RaisePropertyChanged(() => OrderPayments);
     }
  }

The ViewModel ViewModel

   public class OrderPaymentVm : ViewModelBase
   {

      private RelayCommand _copyPaymentTransactionId;
      public DateTime PaymentTime { get; set; }
      public PaymentType PaymentType { get; set; }
      public string Explanation { get; set; }
      public string PaymentTransactionId { get; set; }
      public decimal Amount { get; set; }
      public RelayCommand CopyPaymentTransactionId
      {
         get { return _copyPaymentTransactionId ?? (_copyPaymentTransactionId = new RelayCommand(ExecuteCopyPaymentTransactionId)); }
      }

      private void ExecuteCopyPaymentTransactionId()
      {
         Clipboard.SetText(string.IsNullOrWhiteSpace(PaymentTransactionId) ? string.Empty : PaymentTransactionId);
      }

   }

I have the following xaml 我有以下xaml

<ListView Grid.Row="1" ItemsSource="{Binding OrderPayments}" HorizontalAlignment="Stretch" Margin="0,0,0,1">
      <ListView.ContextMenu>
         <ContextMenu>
            <MenuItem Header="Copy Transaction Id"
                  Command="{Binding CopyPaymentTransactionId}"
                  CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}" />
         </ContextMenu>
      </ListView.ContextMenu>
      <ListView.View>
         <GridView>
            <GridViewColumn HeaderContainerStyle="{StaticResource HeaderLeftAlign}" Header="Transaction Id" Width="150" DisplayMemberBinding="{Binding PaymentTransactionId}" />
            <GridViewColumn HeaderContainerStyle="{StaticResource HeaderLeftAlign}" Header="Time" Width="150" DisplayMemberBinding="{Binding PaymentTime}" />
            <GridViewColumn HeaderContainerStyle="{StaticResource HeaderLeftAlign}" Header="Payment Type" Width="100" DisplayMemberBinding="{Binding PaymentType}" />
            <GridViewColumn HeaderContainerStyle="{StaticResource HeaderLeftAlign}" Header="Amount" Width="80" DisplayMemberBinding="{Binding Amount, StringFormat='{}{0:C}'}" />
            <GridViewColumn HeaderContainerStyle="{StaticResource HeaderLeftAlign}" Header="Explanation" Width="280" DisplayMemberBinding="{Binding Explanation}" />
         </GridView>
      </ListView.View>
</ListView>

Problem 1 the xaml designer says there is a problem with the GridViewColumn bindings, it underlines them and says it cannot resolve property, however it compiles and works fine 问题1 xaml设计器说GridViewColumn绑定有问题,它在下划线并表示无法解析属性,但是可以编译并正常工作

Problem 2 The ConextMenu Command is not hitting the viewmodel command RelayCommand CopyPaymentTransactionId 问题2 ConextMenu命令没有命中viewmodel命令RelayCommand CopyPaymentTransactionId

Im sure these are simple issues however im spinning my wheels, does any one have any suggestions? 我肯定这些都是简单的问题,但是不管我在转动我的轮子,有没有人有任何建议?

Thanks 谢谢

here is solution for the 2nd problem. 这是第二个问题的解决方案。 as the context menu is hosted in a popup, which does not inherit the data context from it's parent as it is a separate root element. 因为上下文菜单位于一个弹出窗口中,该弹出窗口不会从其父项继承数据上下文,因为它是一个单独的根元素。 so you may not simply bind to the parent element's view model. 因此您可能不只是绑定到父元素的视图模型。

here is example to bind the command in a context menu 这是将命令绑定到上下文菜单中的示例

Command="{Binding PlacementTarget.SelectedItem.CopyPaymentTransactionId,
                  RelativeSource={RelativeSource AncestorType=ContextMenu}}"

similar to command parameter, you need to specify the source for the command binding. 与命令参数类似,您需要指定命令绑定的源。

to simplify you may also write the same as 为了简化,您也可以写成

<MenuItem Header="Copy Transaction Id"
          DataContext="{Binding PlacementTarget.SelectedItem, 
                                RelativeSource={RelativeSource AncestorType=ContextMenu}}"
          Command="{Binding CopyPaymentTransactionId}"
          CommandParameter="{Binding}" />

Problem 1: This is because the designer does not know what the type of objects are in the GridView . 问题1:这是因为设计人员不知道GridView中对象的类型。 You know this, so you can do something like this: 您知道这一点,因此您可以执行以下操作:

<Window ... blah blah blah
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    blah blah...

And in ListView : ListView

<ListView blah blah
    d:DataContext="{d:DesignInstance whatevernamespace:WhateverVMYouUse}...

Usually explicitly creating DesignInstance data contexts like this give you better auto complete and removes the superfluous errors that show up in designer. 通常,像这样显式创建DesignInstance数据上下文可以使您更好地自动完成,并消除设计器中显示的多余错误。

Problem 2: Pushpraj beat me to it. 问题2:Pushpraj击败了我。 also see this question 也看到这个问题

 public class OrderPaymentVm : ViewModelBase
 {

  public OrderPaymentVm ()
  {
     CopyPaymentTransactionId = new RelayCommand(ExecuteCopyPaymentTransactionId));
  }

.
.
.

  public RelayCommand CopyPaymentTransactionId
  {
     get; set;
  }

  private void ExecuteCopyPaymentTransactionId()
  {
     Clipboard.SetText(string.IsNullOrWhiteSpace(PaymentTransactionId) ? string.Empty : PaymentTransactionId);
  }

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM