如何将带有 contextMenu 的 WPF ListView 绑定到 viewModel
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25777880/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to bind a WPF ListView with contextMenu to viewModel
提问by TheGeneral
I'm trying to bind a listview to List<OrderPaymentVm> OrderPaymentswith a right click contextmenu to get the PaymentTransactionId.
我正在尝试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
视图模型
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 1the 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
问题 1xaml 设计者说 GridViewColumn 绑定有问题,它在它们下划线并说它无法解析属性,但是它编译并且工作正常
Problem 2The ConextMenu Command is not hitting the viewmodel command RelayCommand CopyPaymentTransactionId
问题 2ConnextMenu 命令没有命中 viewmodel 命令RelayCommand CopyPaymentTransactionId
Im sure these are simple issues however im spinning my wheels, does any one have any suggestions?
我确定这些都是简单的问题,但是我正在转动我的轮子,有人有什么建议吗?
Thanks
谢谢
回答by pushpraj
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}" />
回答by nakiya
Problem 1: This is because the designer does not know what the type of objects are in the GridView. You know this, so you can do something like this:
问题 1:这是因为设计者不知道GridView. 你知道这一点,所以你可以做这样的事情:
<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. also see this question
问题 2:Pushpraj 打败了我。也看到这个问题
回答by Scott Nimrod
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);
}
}
}

