我有一个 TextBlock(s) 的 ListBox,我希望最终用户能够从显示器复制文本,然后他们可以将其粘贴到他们喜欢的位置。我可以通过右键单击-> 复制和用户的 ctrl+c 键来获得单行副本。我还可以通过用户的 ctrl+c 按键获得多行副本。我希望能够通过右键单击-> 复制功能以及从菜单下拉调用进行多行复制。
我的列表框:
<!--Progress Window-->
<ListBox x:Name="Progress_Window" ItemsSource="{Binding _displayString}" ScrollViewer.ScrollChanged="Progress_Window_ScrollChanged" KeyDown="Progress_Window_KeyDown" SelectionMode="Extended">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding _string}" Foreground="{Binding _color}" FontSize="{Binding _fontSize}">
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Command="Copy">
<MenuItem.CommandBindings>
<CommandBinding Command="ApplicationCommands.Copy" CanExecute="RightClickCopyCmdCanExecute" Executed="RightClickCopyCmdExecuted" />
</MenuItem.CommandBindings>
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
后面的代码:
[DllImport("user32.dll", SetLastError = true)]
static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
[DllImport("kernel32.dll")]
static extern bool GenerateConsoleCtrlEvent(uint dwCtrlEvent, uint dwProcessGroupId);
public const int KEYEVENTF_EXTENDEDKEY = 0x0001; //Key down flag
public const int KEYEVENTF_KEYUP = 0x0002; //Key up flag
public const int VK_LCONTROL = 0xA3; //0xA2; //Left Control key code
public const int C = 0x43; //A Control key code
private void Progress_Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.C && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
try
{
ListBox lb = (ListBox)(sender);
string collectedText = "";
foreach (DisplayData dd in lb.SelectedItems)
{
collectedText += dd._string + "\r\n";
}
if (lb.SelectedItems != null)
{
Clipboard.SetText(collectedText);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
private void RightClickCopyCmdExecuted(object sender, ExecutedRoutedEventArgs e)
{
MenuItem mi = (MenuItem)sender;
DisplayData selected = (DisplayData)mi.DataContext;
if (selected != null)
{
Clipboard.SetText(selected._string);
}
}
private void RightClickCopyCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
public void CallKeyDown()
{
//Progress_Window.Focus();
//// Hold Control down and press C
//keybd_event(VK_LCONTROL, 0, 0, 0);
//keybd_event(C, 0, 0, 0);
//keybd_event(C, 0, KEYEVENTF_KEYUP, 0);
//keybd_event(VK_LCONTROL, 0, KEYEVENTF_KEYUP, 0);
System.Windows.Forms.SendKeys.SendWait("^{c}");
var key = Key.C; // Key to send
var target = Progress_Window; // Target element
var routedEvent = Keyboard.KeyDownEvent; // Event to send
target.RaiseEvent(new KeyEventArgs(Keyboard.PrimaryDevice, PresentationSource.FromVisual(target), 0, key) { RoutedEvent = routedEvent });
}
}
从菜单下拉菜单中:
<Grid>
<Menu>
<!--File-->
<MenuItem Header="_File">
<MenuItem Header="_Close" Command="{Binding Close}" />
</MenuItem>
<!--Edit-->
<MenuItem Header="_Edit">
<MenuItem Header="_Copy Ctrl+C" Command="{Binding CtrlC}" />
</MenuItem>
CtrlC 命令调用触发 CallKeyDown() 的动作。
我试图将我的 ContextMenu 从 TextBlock 移动到 ListBox,但这给了我 ViewModel 的 DataContext 而不是给我 _displayString 数据。
正如您在 CallKeyDown() 中看到的那样,我试图从后面的代码中模拟 ctrl+c 按键,但没有成功。我不知道这是否是解决这个问题的最佳方法。我也尝试使用 SendKeys.Send("^{c}") 但这仅适用于窗口窗体。