3

C#/。NET 2.0で記述されたWindowsアプリケーションに[コピー]メニュー項目を実装するにはどうすればよいですか?

ユーザーがコントロール内のテキストにマークを付けてから、アプリケーションのメニューバーの[編集]メニューから[コピー]メニュー項目を選択し、Excelなどで貼り付けを実行できるようにします。

私の頭を回転させるのは、最初にどの子フォームがアクティブであるかを判別し、次にクリップボードにコピーする必要があるマークされたテキストを含むコントロールを見つける方法です。

助けてください。

4

5 に答える 5

5

私の同僚と私が思いついた重いペアプログラミングの助けを借りて、自由にリファクタリングしてください。

コードはメイン フォームに配置されます。copyToolStripMenuItem_Click メソッドは、[編集] メニューの [コピー] メニュー項目の Click イベントを処理します。

    /// <summary>
    /// Recursively traverse a tree of controls to find the control that has focus, if any
    /// </summary>
    /// <param name="c">The control to search, might be a control container</param>
    /// <returns>The control that either has focus or contains the control that has focus</returns>
    private Control FindFocus(Control c) 
    {
        foreach (Control k in c.Controls)
        {
            if (k.Focused)
            {
                return k;
            }
            else if (k.ContainsFocus)
            {
                return FindFocus(k);
            }
        }

        return null;
    }

    private void copyToolStripMenuItem_Click(object sender, EventArgs e)
    {
        Form f = this.ActiveMdiChild;

        // Find the control that has focus
        Control focusedControl = FindFocus(f.ActiveControl);

        // See if focusedControl is of a type that can select text/data
        if (focusedControl is TextBox)
        {
            TextBox tb = focusedControl as TextBox;
            Clipboard.SetDataObject(tb.SelectedText);
        }
        else if (focusedControl is DataGridView)
        {
            DataGridView dgv = focusedControl  as DataGridView;
            Clipboard.SetDataObject(dgv.GetClipboardContent());
        }
        else if (...more?...)
        {
        }
    }
于 2008-09-15T14:36:59.983 に答える
1

開いているウィンドウを判別するには、Form.ActiveMDIChildプロパティを照会して、現在アクティブなウィンドウへの参照を取得します。そこから、次の2つのいずれかを実行できます。

1)新しいパブリックメンバー関数GetCopiedData()を持つ独自のカスタムFormクラス(たとえばFormFoo)を作成し、そのクラスからアプリケーションのすべての子フォームを継承する場合は、次のようにすることができます。

((FormFoo)this.ActiveMDIChild).GetCopiedData();

GetCopiedData関数には、クリップボードにコピーする必要のあるテキストを検出するためのフォーム固有の実装があると想定しています。

また

2)継承を使用して、アクティブなフォームのタイプを検出し、フォームのタイプに応じてコピーされたデータを取得するために何かを行うことができます。

Form f = this.ActiveMDIChild;
if(f is FormGrid)
{
    ((FormGrid)f).GetGridCopiedData();
} else if(f is FormText) {
    ((FormText)f).GetTextCopiedData();
}

これで、アクティブなウィンドウの検索とコピー機能の実装方法を開始できます。GridViewからのコピーについてさらにサポートが必要な場合は、別の質問を投稿することをお勧めします。

于 2008-09-15T13:45:59.123 に答える
0

フォームがタブ付きで、ターゲット コントロールが DataGridView の場合、DataGridView を右クリックすると、上記の方法を使用して、フォームの TabControl がアクティブ コントロールとして返されることがあります。

DataGridView に次のハンドラーを実装することで、これを回避しました。

private void dataGridView_CellMouseDown(オブジェクト送信者、DataGridViewCellMouseEventArgs e)

{

 if (e.Button == MouseButtons.Right)
 {
      dataGridView.Focus();

      dataGridView.CurrentCell = dataGridView[e.ColumnIndex, e.RowIndex];
 }

}

于 2009-07-30T15:38:30.303 に答える
0

コントロールを拡張しない理由は、コントロール自体がクリップボードにコピーする必要があるデータを提供するためです。

ApplicationCommandsのドキュメントをご覧ください。

于 2008-09-15T13:33:41.150 に答える
-1

これをより小さなタスク/質問に分割したほうがよいように思えます。聞こえ方にこだわっている問題がいくつかあります。

複数の「子」ウィ​​ンドウが開いています。これは MDI アプリケーションですか? これらの子ウィンドウの 1 つでアクションが実行されると、そのウィンドウのイベント ハンドラーでイベントが発生する必要があります。それが最初に設定することです。これが datagridview の場合は、簡単なテストを開始することをお勧めします。DataGridView.SelectionChangedイベントをトラップしてみてください。今のようなものを投げ込むだけMessageBox.Show("I copied your datas!");です。

これにより、少なくともこのイベントがどのように発生するかを理解できるところから始められるはずです。

ここから、データグリッドと、行とそれらの行の子コントロールについてもう少し知る必要があります。次に、適切なスコープで、適切なタイミングで発生する render イベントでイベントを作成できる可能性があります。

于 2008-09-15T13:24:37.660 に答える