我有一个TextBlock的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()的Action。
我试图将我的ContextMenu从TextBlock移动到ListBox,但这给了我ViewModel的DataContext而不是给我_displayString数据。
正如你在CallKeyDown()中看到的那样,我试图从后面的代码模拟一个ctrl + c键按下但没有成功。我不知道这是否是解决这个问题的最佳方法。我也尝试使用SendKeys.Send(“^ {c}”),但这只适用于Window Forms。
答案 0 :(得分:3)
我只需要将RightClickCopyCmdExecuted
中的代码复制到CallKeyDown()
,一切都很顺利。然后我会从CallKeyDown
致电RightClickCopyCmdExecuted
。
我在列表框中获得了右键单击&gt;副本的多行。 所以我的ListBox变成了:
<!--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}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Command="Copy">
<MenuItem.CommandBindings>
<CommandBinding Command="ApplicationCommands.Copy" CanExecute="RightClickCopyCmdCanExecute" Executed="RightClickCopyCmdExecuted" />
</MenuItem.CommandBindings>
</MenuItem>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
后面的代码变成了:
private void RightClickCopyCmdExecuted(object sender, ExecutedRoutedEventArgs e)
{
string collectedText = "";
foreach (DisplayData dd in Progress_Window.SelectedItems)
{
collectedText += dd._string + "\r\n";
}
if (Progress_Window.SelectedItems != null)
{
Clipboard.SetText(collectedText);
}
}