Caliburn.Micro: 如何将函数绑定到DataGrid的RowDetailsTemplate中的上下文菜单项?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Caliburn.Micro: 如何将函数绑定到DataGrid的RowDetailsTemplate中的上下文菜单项?相关的知识,希望对你有一定的参考价值。
我有一个Items的数据表格,其中包括一个行细节的SubItems数据表格。在主 "Items "数据表格中,有一个上下文菜单,它带有添加或删除项目的功能,这工作得很好。还有一个上下文菜单,用于行细节数据表格 "SubItems",有类似的功能,但我无法正确绑定。如果执行,我得到以下异常 "System.Exception: 'No target found for method AddSubItem.'"。
我已经拼命尝试了许多其他帖子上建议的解决方案,但到目前为止没有任何工作。我很感激任何见解。以下是我的测试代码。
ShellViewModel:
using System;
using Caliburn.Micro;
using ContextMenuTest.Models;
namespace ContextMenuTest.ViewModels
{
public class ShellViewModel : Screen
{
public static Random rnd = new Random();
private BindableCollection<ItemModel> items = new BindableCollection<ItemModel>();
public BindableCollection<ItemModel> Items
{
get { return items; }
set
{
items = value;
NotifyOfPropertyChange(() => Items);
}
}
private ItemModel selectedItem = new ItemModel(rnd);
public ItemModel SelectedItem
{
get { return selectedItem; }
set
{
selectedItem = value;
NotifyOfPropertyChange(() => SelectedItem);
}
}
private SubItemModel selectedSubItem = new SubItemModel(rnd);
public SubItemModel SelectedSubItem
{
get { return selectedSubItem; }
set
{
selectedSubItem = value;
NotifyOfPropertyChange(() => SelectedSubItem);
}
}
public ShellViewModel()
{
for(int i = 0; i < 10; i++)
{
Items.Add(new ItemModel(rnd));
}
}
public void AddItem()
{
Items.Add(new ItemModel(rnd));
}
public void RemoveItem()
{
Items.Remove(SelectedItem);
}
public void AddSubItem(object e)
{
var _item = e as ItemModel;
_item.SubItems.Add(new SubItemModel(rnd));
}
public void RemoveSubItem(object e)
{
var _item = e as ItemModel;
_item.SubItems.Remove(SelectedSubItem);
}
}
}
ShellView:
<Window x:Class="ContextMenuTest.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ContextMenuTest.Views"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
Title="ShellView" Height="450" Width="800"
>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DataGrid x:Name="Items" Grid.Row="0" AutoGenerateColumns="False" CanUserResizeColumns="True" CanUserAddRows="false"
VerticalAlignment="Stretch" VerticalScrollBarVisibility="Auto" MinHeight="100" SelectedItem="{Binding SelectedItem}">
<DataGrid.ContextMenu>
<ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Add Item" cal:Message.Attach="AddItem()"/>
<MenuItem Header="Remove Item" cal:Message.Attach="RemoveItem()"/>
</ContextMenu>
</DataGrid.ContextMenu>
<DataGrid.Columns >
<DataGridTextColumn Header="ID" Binding="{Binding Path=ID, UpdateSourceTrigger=PropertyChanged}" Width="*" IsReadOnly="True"/>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid ItemsSource="{Binding Path=SubItems}" AutoGenerateColumns="False" CanUserResizeColumns="True" CanUserAddRows="false"
VerticalAlignment="Stretch" VerticalScrollBarVisibility="Auto" MinHeight="100"
SelectedItem="{Binding Path=SelectedSubItem, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}">
<DataGrid.ContextMenu>
<ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Add Sub Item" cal:Message.Attach="AddSubItem($dataContext)"/>
<MenuItem Header="Remove Sub Item" cal:Message.Attach="RemoveSubItem($dataContext)"/>
</ContextMenu>
</DataGrid.ContextMenu>
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding Path=ID}" Width="auto" IsReadOnly="True"/>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged}" Width="auto"/>
<DataGridTextColumn Header="Value" Binding="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged}" Width="auto"/>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</Grid>
</Window>
ItemModel.ShellViewModel:ShellView:ItemModel。
using Caliburn.Micro;
using System;
namespace ContextMenuTest.Models
{
public class ItemModel
{
public Guid ID { get; set; }
public string Name { get; set; }
public BindableCollection<SubItemModel> SubItems { get; set; } = new BindableCollection<SubItemModel>();
public ItemModel(Random rnd)
{
ID = Guid.NewGuid();
Name = "Item " + ID.ToString().Substring(3, 5);
for (int i = 0; i < 5; i++)
{
SubItems.Add(new SubItemModel(rnd));
}
}
}
}
SubItemModel:
using System;
namespace ContextMenuTest.Models
{
public class SubItemModel
{
public Guid ID { get; set; }
public string Name { get; set; }
public int Value { get; set; }
public SubItemModel(Random rnd)
{
ID = Guid.NewGuid();
Name = "SubItem " + ID.ToString().Substring(3,5);
Value = rnd.Next();
}
}
}
尝试使用TagHelper。它可以满足你的要求,示例代码如下。
<Grid Background="White" HorizontalAlignment="Stretch" Height="200" Name="GridLayout">
<ListBox x:Name="ListBoxItems">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Tag="{Binding DataContext, ElementName=GridLayout}">
<Grid.ContextMenu>
<ContextMenu Name="cm" cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Open"
cal:Message.Attach="Open($dataContext)">
</MenuItem>
</ContextMenu>
</Grid.ContextMenu>
<TextBlock VerticalAlignment="Center">
.. text..
</TextBlock>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
以上是关于Caliburn.Micro: 如何将函数绑定到DataGrid的RowDetailsTemplate中的上下文菜单项?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 ValueConverter 应用于基于约定的 Caliburn.Micro 绑定示例?
使用 Caliburn.Micro 将命令绑定到 ListView 内的按钮
Caliburn Micro:如何设置绑定 UpdateSourceTrigger?
使用 Caliburn Micro 将 WebView2 绑定到 ViewModel