C# 将ContextMenu绑定到DataGridCell内容以复制内容
我以前做过ContextMenus,但对于DataGrid来说,它们似乎太复杂了。我只想把单元格的内容复制到剪贴板上。我怎样才能让它工作?似乎有很多选择,但没有一套保证的方法C# 将ContextMenu绑定到DataGridCell内容以复制内容,c#,wpf,mvvm,datagrid,C#,Wpf,Mvvm,Datagrid,我以前做过ContextMenus,但对于DataGrid来说,它们似乎太复杂了。我只想把单元格的内容复制到剪贴板上。我怎样才能让它工作?似乎有很多选择,但没有一套保证的方法 <DataGrid ItemsSource="{Binding MyStuff}"> <DataGridTextColumn Binding="{Binding MyContentIWantToCopy}"> <DataGridTextColumn.CellSt
<DataGrid ItemsSource="{Binding MyStuff}">
<DataGridTextColumn Binding="{Binding MyContentIWantToCopy}">
<DataGridTextColumn.CellStyle>
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Command="ApplicationCommands.Copy"/>
</ContextMenu>
</Setter.Value>
</Setter>
<DataGridTextColumn.CellStyle>
</DataGridTextColumn>
</DataGrid>
理想情况下,这是最简单的方法。但当然,这是行不通的
不过,我也尝试过命令-
这些都不管用。通常结果是出现一个上下文菜单,灰显按钮或不执行任何操作的按钮都不会触发命令。我只想将Datagrid单元格中的文本复制到剪贴板中。我以前以类似的方式在所有类型的对象上都这样做过——甚至是ListView——但我找不到DataGrid和DataGridTextColumns的任何解决方案。消息开头的xaml代码包含错误。但即使在修复之后,似乎也需要复制整行而不是一个单元格 一个简单的变体-只需编写自己的命令,例如:
public class MyCopyCommand : ICommand
{
public string Name { get { return "Copy"; } }
public void Execute(object parameter)
{
Clipboard.SetText(parameter != null ? parameter.ToString() : "<null>");
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
}
公共类MyCopyCommand:ICommand
{
公共字符串名称{get{返回“Copy”;}
public void Execute(对象参数)
{
Clipboard.SetText(参数!=null?参数.ToString():“”);
}
公共布尔CanExecute(对象参数)
{
返回true;
}
公共事件处理程序CanExecuteChanged;
}
此命令认为该参数已包含要复制的必需字符串。但您可以根据需要自定义它的逻辑,例如,获取整个DataGridCell并决定从中复制什么。
第二步-在XAML中使用我们的命令,例如通过参考资料:
<Window
x:Class="WpfApplication65.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:app="clr-namespace:WpfApplication65"
>
<Window.Resources>
<app:MyCopyCommand x:Key="CopyCommand"/>
</Window.Resources>
<Grid>
<DataGrid x:Name="MyDataGrid">
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem
Command="{StaticResource CopyCommand}"
CommandParameter="{Binding Path=Parent.PlacementTarget.Content.Text, RelativeSource={RelativeSource Self}}"
Header="{Binding Name, Source={StaticResource CopyCommand}}"
/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</DataGrid.CellStyle>
</DataGrid>
</Grid>
如果“WpfApplication65”只是我的项目名称,您当然必须插入您的项目名称。
在这里,我按原样编写了CommandParameter绑定路径,因为我知道DataGrid将自动生成DataGridCell,其内容属性中包含TextBlock。如果您想要通用解决方案-将CommandParameter绑定到Parent.PlacementTarget,您将把DataGridCell实例获取到MyCopyCommand.Execute方法,然后使用它和它的列属性-从中获取您想要的内容
要使DataGrid正常工作,请将以下代码添加到MainWindow类:
public class MyData
{
public string Name { get; set; }
public int Count { get; set; }
public MyData(string name, int count)
{
Name = name;
Count = count;
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var data = new List<MyData>
{
new MyData("one", 10),
new MyData("two", 100500),
new MyData("three", 777)
};
MyDataGrid.ItemsSource = data;
}
}
公共类MyData
{
公共字符串名称{get;set;}
公共整数计数{get;set;}
公共MyData(字符串名称、整数计数)
{
名称=名称;
计数=计数;
}
}
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
var数据=新列表
{
新MyData(“一”,10),
新MyData(“两个”,100500),
新MyData(“三”,777)
};
MyDataGrid.ItemsSource=数据;
}
}
希望这有帮助,如果有些东西不起作用,请询问我。XAML:
<DataGrid x:Name="MyDataGrid">
<DataGridTextColumn Binding="{Binding MyContentIWantToCopy}">
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="Copy" Click="MenuItem_OnClick"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</DataGrid.CelStyle>
</DataGridTextColumn>
</DataGrid>
我认为您还可以在XAML中使用属性CommandTarget
,而不是使用代码隐藏
void MenuItem_OnClick(object sender, RoutedEventArgs e)
{
ApplicationCommands.Copy.Execute(null, MyDataGrid);
}