title: Copy multiple items in ListBox to ClipBoard
body: <p>I have a ListBox of TextBlock(s) that I would like the end user to be able to copy the text from the display and then they can paste it to where they like. I am able to get a single line copy with the right click-> copy, and with a user's ctrl+c key press. I am also able to get a multiple line copy with a user's ctrl+c key press. I would like to be able to do a multiple line copy with the right click->copy feature as well as from a Menu drop down call.</p>
  
  <p>My ListBox:</p>
  
  <pre><code>    &lt;!--Progress Window--&gt;
      &lt;ListBox x:Name="Progress_Window" ItemsSource="{Binding _displayString}" ScrollViewer.ScrollChanged="Progress_Window_ScrollChanged" KeyDown="Progress_Window_KeyDown" SelectionMode="Extended"&gt;
          &lt;ListBox.ItemTemplate&gt;
              &lt;DataTemplate&gt;
                  &lt;TextBlock Text="{Binding _string}" Foreground="{Binding _color}" FontSize="{Binding _fontSize}"&gt;
  
                      &lt;TextBlock.ContextMenu&gt;
                          &lt;ContextMenu&gt;
                              &lt;MenuItem Command="Copy"&gt;
                                  &lt;MenuItem.CommandBindings&gt;
                                      &lt;CommandBinding Command="ApplicationCommands.Copy" CanExecute="RightClickCopyCmdCanExecute" Executed="RightClickCopyCmdExecuted" /&gt;
                                  &lt;/MenuItem.CommandBindings&gt;
                              &lt;/MenuItem&gt;
                          &lt;/ContextMenu&gt;
                      &lt;/TextBlock.ContextMenu&gt;
  
                  &lt;/TextBlock&gt;
              &lt;/DataTemplate&gt;
          &lt;/ListBox.ItemTemplate&gt;
      &lt;/ListBox&gt;
  </code></pre>
  
  <p>The code behind:</p>
  
  <pre><code>    [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 &amp;&amp; (Keyboard.Modifiers &amp; 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 });
      }
  }
  </code></pre>
  
  <p>From the Menu drop down:</p>
  
  <pre><code>&lt;Grid&gt;
      &lt;Menu&gt;
          &lt;!--File--&gt;
          &lt;MenuItem Header="_File"&gt;
              &lt;MenuItem Header="_Close" Command="{Binding Close}" /&gt;
          &lt;/MenuItem&gt;
  
          &lt;!--Edit--&gt;
          &lt;MenuItem Header="_Edit"&gt;
              &lt;MenuItem Header="_Copy     Ctrl+C" Command="{Binding CtrlC}" /&gt;
          &lt;/MenuItem&gt;
  </code></pre>
  
  <p>CtrlC command calls an Action that triggers CallKeyDown(). </p>
  
  <p>I have tried to move my ContextMenu from the TextBlock to the ListBox, but that gave me the DataContext of my ViewModel instead of giving me the _displayString data. </p>
  
  <p>As you can see in CallKeyDown() I am trying to simulate a ctrl+c key press from code behind with no success. I don't know if that is the best approach to this problem. I also tried to use SendKeys.Send("^{c}") but that only works with Window Forms.</p>