【问题标题】:Listview with copy-paste带有复制粘贴的列表视图
【发布时间】:2011-03-03 01:29:10
【问题描述】:

是否有一种简单的方法可以为列表视图添加复制粘贴,或者我应该改用 DataGridView 吗?

我的应用程序有点像地址簿,它包含电子邮件、数字等,其中复制粘贴很有用。

【问题讨论】:

    标签: c# winforms listview copy-paste


    【解决方案1】:

    下面的示例将 Ctrl-C 作为复制到剪贴板命令,并从所有选定的行中复制第二列的值:

        private void resultsListView_KeyUp(object sender, KeyEventArgs e)
        {
            if (sender != resultsListView) return;
    
            if (e.Control && e.KeyCode == Keys.C)
                CopySelectedValuesToClipboard();
        }
    
        private void CopySelectedValuesToClipboard()
        {
            var builder = new StringBuilder();
            foreach (ListViewItem item in resultsListView.SelectedItems)
                builder.AppendLine(item.SubItems[1].Text);
    
            Clipboard.SetText(builder.ToString());
        }
    

    第一列使用item.Text,其他列使用item.SubItems[n].Text

    参考资料:

    1. What is the KeyChar for Ctrl+C and Ctrl+V in C# 获取密钥和正确的事件处理程序。
    2. Copy ListView to Clipboard in VB.NET, C#, and VB6 获取将 ListView 复制到剪贴板的完整示例。

    【讨论】:

    • 很好的解决方案,我只需要通过KeyDown 事件来做到这一点。 KeyUp 不起作用,因为当按下 c 时,它会自动选择 ListBox 中以 c 开头的第一个条目,从而将我的多选呈现为一个。
    • 我对@9​​87654330@ 的期望无效,而我不得不使用builder.AppendLine(item.Text);
    【解决方案2】:

    手动复制和粘贴并不难,只需为KeyDown(或者可能是KeyPress 不记得但相当肯定它之一)放入一个事件处理程序并检查按下了什么键查看e.KeyCode 并检查e.Control 是否为真。如果它是 xcv 之一,只需调用 Clipboard.SetTextClipboard.GetText 即可在剪贴板中写入/读取。
    有关 Clipboard 类的 MSDN 文档,请参阅 here

    您也可以在 ListView 上添加一个带有复制和粘贴功能的上下文菜单以使其完整。

    【讨论】:

    • 问题在于我只能复制整行,除非有一些巧妙的技巧可以选择单元格。
    • @Zubirg:是的,我忘了ListView 中没有单元格,切换到DataGridView 可能更容易。但是,如果您确实想坚持使用ListView,您可以对其进行处理ClickMouseDown 事件以计算单击了哪个子项,然后更改该子项的BackColor 使其看起来被选中然后您可以处理该子项的复制和粘贴。您必须确保在项目上设置UseItemStyleForSubItems = false;,否则颜色不会显示在子项目上。
    【解决方案3】:

    我已将其作为方法(取决于@brett 的最佳答案),因此只需在表单初始化时执行一次:copyableListView(myListView),它就会自行完成。

    代码:

    private void copyableListView(ListView listView)
    {
        listView.KeyDown += (object sender, KeyEventArgs e) =>
        {
            if (!(sender is ListView)) return;
    
            if (e.Control && e.KeyCode == Keys.C)
            {
                var builder = new StringBuilder();
                foreach (ListViewItem item in (sender as ListView).SelectedItems)
                    builder.AppendLine(item.Text + Environment.NewLine);
                Clipboard.SetText(builder.ToString());
            }
        };
    }
    

    此外,在表单销毁时,您应该有删除所有订阅事件的方法,即

    void myDeinit()
    {
        myListView=null;
        myListView2=null;
        ...
    }
    

    【讨论】:

      【解决方案4】:

      我的要求是添加一个按钮以将序列号列表复制到剪贴板。我以正常方式添加按钮,然后添加以下方法:

      private void btnClipboard_Click(object sender, EventArgs e)
      {
          String clipText = string.Empty;
          foreach (ListViewItem item in lstSerials.Items)
          {
              clipText += item.SubItems[0].Text;
              clipText += Environment.NewLine;
          }
          if (!String.IsNullOrEmpty(clipText))
          {
              Clipboard.SetText(clipText);
          }
      }
      

      【讨论】:

      • 为什么我的投票被否决了?此实现有效!
      【解决方案5】:

      根据@Brett 的回答,我编写了这个方法,它复制整个选定的行而不是仅仅复制一列(当 FullRowSelect = true 时特别​​好)。

      另外两个改进:

      1.忽略任何换行符 - 就像 ListView 一样。

      2. 未选择行时避免异常 - 只需清除剪贴板即可。

      private void ListViewLogs_KeyDown(object sender, KeyEventArgs e)
      {
          CopySelectedRowsToClipboard(listViewLogs, e);
      }
      
      private void CopySelectedRowsToClipboard(ListView listView, KeyEventArgs e)
      {
          if (e.Control && e.KeyCode == Keys.C)
          {
              var builder = new StringBuilder();
              foreach (ListViewItem item in listView.SelectedItems)
              {
                  var subItems = item.SubItems.Cast<ListViewItem.ListViewSubItem>()
                      .Select(subItem => subItem.Text);
                  builder.AppendLine(string.Join(", ", subItems).Replace(Environment.NewLine, ""));
              }
      
              if (builder.Length > 0)
                  Clipboard.SetText(builder.ToString());
              else
                  Clipboard.Clear();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-28
        • 2016-09-05
        相关资源
        最近更新 更多