我有一个类用户,其中包含一些string和int类型的字段,我有一个显示这些字段的数据网格,我希望用户能够选择一行并按 CTRL + < kbd> C 将行所代表的对象复制到剪贴板,当用户按下 CTRL + V (当焦点在数据网格上时)将添加数据网格的新行。 代码:
xaml中的:
<DataGrid KeyDown="dgKeyDown" SelectionMode="Single" Name="dg1"
AutoGenerateColumns="False" CanUserAddRows="True"
CopyingRowClipboardContent="dg1Users_CopyingRowClipboardContent">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="Auto" Binding="{Binding Name}"/>
<DataGridTextColumn Header="ID" Width="Auto" Binding="{Binding ID}" />
<DataGridTextColumn Header="Age" Width="Auto" Binding="{Binding Age}"/>
</DataGrid.Columns>
</DataGrid>
dg1项目源设置为可观察的用户对象集合:
dg1.ItemsSource = dg1Users;
以及复制和粘贴事件:
private void dg1Users_CopyingRowClipboardContent(object sender, DataGridRowClipboardEventArgs e)
{
User a = dg1.SelectedItem as User;
if (a != null)
{
Clipboard.Clear();
Clipboard.SetData("User1", a);
}
}
private void dgKeyDown(object sender, KeyEventArgs e)
{
User a = null;
if (e.Key == Key.V && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
if(Clipboard.ContainsData("User1"))
{
a = (User)Clipboard.GetData("User1");
dg1Users.Add(a);
}
}
}
它不起作用,没有任何反应,使用一些打印语句测试我发现当按下 CTRL + V 时,第二个中的代码如果在dgKeyDown中不执行。
我做错了什么?
注意:我没有使用MVVM模式。
答案 0 :(得分:1)
剪贴板有标准格式:
我更喜欢使用registr我的自定义格式。
行, 1)首先设置[Serializable]属性
[Serializable]
public class User
{
public string Name { get; set; }
public string ID { get; set; }
public string Age { get; set; }
}
2)然后注册格式,(我将其保存到属性以进行调试)
public DataFormat format { get; set; }
和
format = DataFormats.GetDataFormat(typeof(User).FullName);
3)然后你可以像这样保存你的对象:
User a = dg1.SelectedItem as User;
if (a != null)
{
IDataObject dataObj = new DataObject();
dataObj.SetData(format.Name, a, true);
Clipboard.SetDataObject(dataObj, true);
}
4)你可以像这样追回对象:
User a = null;
IDataObject dataObj = Clipboard.GetDataObject();
if (dataObj != null && dataObj.GetDataPresent(format.Name))
{
a = dataObj.GetData(format.Name) as User;
dg1Users.Add(a);
}
5)此外,我们还有问题,我不知道现在如何解决
在你的
中private void dg1Users_CopyingRowClipboardContent(object sender, DataGridRowClipboardEventArgs e)
{
}
你应该为应对准备数据。例如,在e.ClipboardRowContent
中将包含来自所选行的数据的字符串。因此,在g1Users_CopyingRowClipboardContent之后,e.ClipboardRowContent中的所有内容都将被复制。因为你的if(Clipboard.ContainsData("User1"))
是假的。因为此时你的剪贴板中存储了字符串。
我更改了代码:
private void dgKeyDown(object sender, KeyEventArgs e)
{
User a = null;
if(e.Key == Key.V && Keyboard.Modifiers == ModifierKeys.Control)
{
IDataObject dataObj = Clipboard.GetDataObject();
if (dataObj !=null && dataObj.GetDataPresent(format.Name))
{
a = dataObj.GetData(format.Name) as User;
dg1Users.Add(a);
}
}
else if (e.Key == Key.B && Keyboard.Modifiers == ModifierKeys.Control)
{
User copingUser = dg1.SelectedItem as User;
if (copingUser != null)
{
IDataObject dataObj = new DataObject();
dataObj.SetData(format.Name, copingUser, true);
Clipboard.SetDataObject(dataObj, true);
}
}
}
在这种情况下,我可以复制粘贴所选项目
编辑:
因为你不使用MVVM,所以你不要使用ApplicationCommands等。
因此,在您的情况下,您可以像这样为Copy build-in命令设置NotACommand。
在此之后,您可以在我的代码中更改else if (e.Key == Key.C && Keyboard.Modifiers == ModifierKeys.Control)
。我测试了它,它可以按你的需要工作。
<DataGrid KeyDown="dgKeyDown" SelectionMode="Single" Name="dg1"
AutoGenerateColumns="False" CanUserAddRows="True">
<DataGrid.InputBindings>
<KeyBinding Key="C" Modifiers="Control" Command="ApplicationCommands.NotACommand"/>
</DataGrid.InputBindings>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Width="Auto" Binding="{Binding Name}"/>
<DataGridTextColumn Header="ID" Width="Auto" Binding="{Binding ID}" />
<DataGridTextColumn Header="Age" Width="Auto" Binding="{Binding Age}"/>
</DataGrid.Columns>
</DataGrid>