2

我有一个 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}") 但这仅适用于窗口窗体。

4

1 回答 1

3

我只需要将我的代码复制RightClickCopyCmdExecutedCallKeyDown()中,一切都很好。然后我会CallKeyDownRightClickCopyCmdExecuted.

我在列表框上获得了右键单击->复制的多行。所以我的 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);
        }
    }
于 2013-10-03T15:46:28.633 回答