DOBON.NET DOBON.NETプログラミング掲示板過去ログ

DataGridのコピー

  • 題名: DataGridのコピー
  • 著者: はる
  • 日時: 2005/02/28 14:23:07
  • ID: 9385
  • この記事の返信元:
    • (なし)
  • この記事への返信:
  • ツリーを表示
分類:[.NET]

DataGridの項目を「Ctrl + C」でコピーすると、選択されている行全てがコピーされてしまいます。右クリックでコピーを行うと選択されている項目がけがコピーされます。選択している項目だけをコピーする場合はどうすればよいのでしょうか?
こんにちは、じゃんぬねっと です。

■No9385に返信(はるさんの記事)
> DataGridの項目を「Ctrl + C」でコピーすると、選択されている行全てがコピーされてしまいます。
> 右クリックでコピーを行うと選択されている項目がけがコピーされます。
> 選択している項目だけをコピーする場合はどうすればよいのでしょうか?

質問前に、過去ログくらいは探しましょう。(^^)
http://dobon.net/cgi-bin/vbbbs/cbbs.cgi?mode=al2&namber=8399&no=0&KLOG=2
どうも失礼しました。

以後気をつけます。

まだ初心者なので記述がよくわからりません。
一応↓のように記述したのですが、正しく動きません。
まず、原因がわからないのは、
[Ctrl] + [c]を押すのだからKeyDownイベントが動きません。

KeyDownイベントで実行するのですよね?

ご指導お願いします。

Private Sub DataGrid_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGrid.KeyDown

Dim ts As DataGridTableStyle
Dim i As Int16
Dim cx As DataGridTextBoxColumn
Dim tb As TextBox

i = i
If e.KeyCode = Keys.Control AndAlso e.KeyCode = Keys.C Then

ts = DG_1.TableStyles("a")
i = DG_1.CurrentCell.ColumnNumber
cx = ts.GridColumnStyles(i)
tb = cx.TextBox
Clipboard.SetDataObject(tb, True)
End If
End Sub
すいません。
またまた載っていました。keyeventのことが載っていました(汗)
もう少し調べてみます。
> もう少し調べてみます。

調べなくても、じゃんぬねっとさんの提示された過去ログ先のbettaさんの最後の投稿に答えがあります。DataGridの代わりにこのDataGridExを使えばいいだけです。
初心者的なことをお聞きします。
DataGridExというクラスを作成するのですよね?

public class DataGridEx : System.Windows.Forms.DataGrid

systemというのは宣言が必要なのでしょうか?(宣言をしてください)
というメッセージが出ます。
1から順に教えてください。
まず、C→VBに変換したのですが、これでよいのでしょうか?

Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean

Const WM_KEYDOWN = "0x100"

If msg.Msg = WM_KEYDOWN Then

  Dim keyCode As Keys = CType(CType(keyData & Keys.KeyCode, Keys, Integer))
If (keyData & Keys.Control) = Keys.Control And keyCode = Keys.C Then

'(選択された文字列をコピーするコードを書く)
'テーブルスタイルの取得
Dim ts As DataGridTableStyle
ts = Me.TableStyles(0)

'選択されている列の取得
Dim cn As Integer = Me.CurrentCell.ColumnNumber

'DataGridTextBoxColumnの取得
Dim cs As DataGridTextBoxColumn = CType(ts.GridColumnStyles(cn), DataGridTextBoxColumn)

'TextBoxの取得
Dim tb As TextBox = cs.TextBox

'クリップボード上にデータを格納
Clipboard.SetDataObject(tb.SelectedText)

Return True
End If
End If
Return MyBase.ProcessCmdKey(msg, keyData)
 End Function
End Class
断言はできませんが、先頭に

Public Class DataGridEx
Inherits System.Windows.Forms.DataGrid

Public Sub New()
MyBase.New()
End Sub

が付いているなら大丈夫でしょう。
すいません。どうも[Ctrl+C]ボタンでつまづいています。
一つのボタンだけならコピーされます。二つ以上のボタンだと認識されません。
keyCodeに[Ctrl]ボタンと[C]ボタンを連結してkeyCodeに格納しているのでしょうか?VBに変換しているところがエラーで返ってきます。
Dim keyCode As Keys = CType(CType(keyData & Keys.KeyCode, Keys, Integer))
              ↓エラーが起きるので下のように変更しました
Dim keyCode As Keys = CType(keyData & Keys.KeyCode, Keys)
これだと、[Ctrl]と[C]ボタンが押されたと認識してくれないのでしょうか?


C↓
Keys keyCode = (Keys)(int)keyData & Keys.KeyCode;
if ((keyData & Keys.Control) == Keys.Control && keyCode == Keys.C)

VB↓
Dim keyCode As Keys = CType(CType(keyData & Keys.KeyCode, Keys, Integer))
If (keyData & Keys.Control) = Keys.Control And keyCode = Keys.C Then
まだ行き詰っています。

Dim keyCode As Keys = CType(keyData & Keys.KeyCode, Keys)
のコードは[C]を取得してくるのでしょうか?
(keyData & Keys.Control) のコードで[Ctrl]を取得してくるのでしょうか?

If (keyData & Keys.Control) = Keys.Control And keyCode = Keys.C Then
     ↑で、[Ctrl]キーが一致      ↑で、[C]キーが一致
ということですよね?

Dim keyCode As Keys = CType(keyData & Keys.KeyCode, Keys)
で取得しているのは[C]という事なんですよね?

どうすれば、このIFの条件を満たすことが出来ますか?
ご教授ください
■No9506に返信(はるさんの記事)
お疲れ様です。JAR所属のbettaです。

> > VB↓
> Dim keyCode As Keys = CType(CType(keyData & Keys.KeyCode, Keys, Integer))
> If (keyData & Keys.Control) = Keys.Control And keyCode = Keys.C Then

Dim keyCode As Keys = CType(CType(keyData, Integer), Keys) And Keys.KeyCode
If (keyData And Keys.Control) = Keys.Control AndAlso keyCode = Keys.C Then

で、ひっかかりませんか?
>>> VB↓
>>Dim keyCode As Keys = CType(CType(keyData & Keys.KeyCode, Keys, Integer))
>>If (keyData & Keys.Control) = Keys.Control And keyCode = Keys.C Then
>
> Dim keyCode As Keys = CType(CType(keyData, Integer), Keys) And Keys.KeyCode
> If (keyData And Keys.Control) = Keys.Control AndAlso keyCode = Keys.C Then
>
> で、ひっかかりませんか?
>
>
>

bettaさんのおっしゃる通りひっかかります。
↑で書いたと思うのですが
Dim keyCode As Keys = CType(keyData & Keys.KeyCode, Keys)
このように変更しました。
(これがいけないのかな・・・?CをVBに変換したのを鵜呑みにしたのがまずいのでしょうか?)
■No9512に返信(はるさんの記事)
お疲れ様です。HSD所属(所属間違えてました)のbettaです。

うーん、何を悩んでいるかよくわかりませんが,
"&"が悪さしてるような気がします。
Cで実行すると、KeyCodeは何が入ってくるのですか?
[Ctrl]+[C]の制御コードが入ってくるのでしょうか?
"[ctrl]の制御コード"+"[c]の制御コード"
みたいに文字列のように連結した形で入ってくるのですか?
こんにちは、じゃんぬねっと です。

■No9514に返信(はるさんの記事)
> Cで実行すると、KeyCodeは何が入ってくるのですか?
> [Ctrl]+[C]の制御コードが入ってくるのでしょうか?
> "[ctrl]の制御コード"+"[c]の制御コード"
> みたいに文字列のように連結した形で入ってくるのですか?

KeyData == KeyCode + 装飾キー だということはご存知ですか?
c,ctrlと入ってくる意味ですか?

実際どう対処すればいいのか教えてください。
こんにちは、じゃんぬねっと です。

■No9528に返信(はるさんの記事)
> c,ctrlと入ってくる意味ですか?

> ------------------------------------------------
> CType(keyData & Keys.KeyCode, Keys)
> ------------------------------------------------

この部分、特にアンパサントが気になったものでして...

> 実際どう対処すればいいのか教えてください。

もう少し、考えてみましょ。
あなたは、今、どの条件のキーを捕捉したいのですか?
[Ctrl] + [C] を捕捉したいのではないのですか?
結果的には
IF KeyCode = Keys.Control And KeyCode = Keys.C Then

こういうことですよね。
テキストボックス等ではこれで通りました

Dim keyCode As Keys = CType(keyData & Keys.KeyCode, Keys)
をどうするかということなんですよね?

Ctype(KeyData,keys) + CType(Keys.Code,Keys)
・・・何が何だかわからなくなってきました。・・・
こんにちは、じゃんぬねっと です。

■No9534に返信(はるさんの記事)
> Dim keyCode As Keys = CType(keyData & Keys.KeyCode, Keys)
> をどうするかということなんですよね?
> 
> Ctype(KeyData,keys) + CType(Keys.Code,Keys)
> ・・・何が何だかわからなくなってきました。・・・

えっと、単純に [Ctrl] + [C] を捕捉するんじゃないんですか?
CType を使わなくとも、Keys 列挙体の型に合わせることができます。
でも、CType() とかわざわざ書いてあるから、私の検討違いですかね...。
もっと複雑なことやろうとしているのでしょうか?

    Protected Overrides Function ProcessCmdKey(...) As Boolean
        If keyData = (Keys.Control Or Keys.C) Then
            MessageBox.Show("[Ctrl] + [C] が押下されたYo!")
            '/ TODO : ここにコピー処理を実装
        End If

        Return MyBase.ProcessCmdKey(msg, keyData)
    End Function
[↑] あ、条件に合致した時の Return True を書くの忘れてました。(^^)
・・・。ご迷惑おかけしました。

単純に[ctrl]+[c]で捕捉すればよかったのですね。(汗)
C→VBに変換する所があったので、そのまま使用していました。
VBに変換されたのが↓のようになっていたで、このように記述をしないと
[Ctr]+[C]は取得できないのかと思っていました。
CType(CType(keyData & Keys.KeyCode, Keys, Integer))

(自分で考えない事が一番いけないですが・・・)

ありがとうございました。
解決済み!
おはようございます、じゃんぬねっと です。
捕捉です。

■No9552に返信(はるさんの記事)
> 単純に[ctrl]+[c]で捕捉すればよかったのですね。(汗)
> C→VBに変換する所があったので、そのまま使用していました。

ちなみに C# も、

    Keys keyCode = (Keys)(int)keyData & Keys.KeyCode;

    if ((keyData & Keys.Control) == Keys.Control && keyCode == Keys.C) {
        // 選択された文字列をコピーするコードを書く
        return true;
    }

ではなく、

    if (keyData == (Keys.Control | Keys.C)) {
        // TODO : ここにコピーを実装
        return true;
    }

のように実装する方が素直です。

Enum のパラメタ結合は、「+」ではなく、「|」(VB.NET だと Or) でやるべきです。
「+-」または「*/」の四則演算子は、int または double に置き換わります。
そのため、ムダなキャストが必要になってしまいます。
解決済み!
> if (keyData == (Keys.Control | Keys.C)) {
> // TODO : ここにコピーを実装
> return true;
> }
>
> のように実装する方が素直です。

この様にすると、Ctrl+C以外ではコピーできないことになりそうですが、例えばCtrl+Shift+Cとしても通常はコピーできるでしょう。このように考えると、前者のような方法になると思うのですが。
2005/03/06(Sun) 15:05:00 編集(投稿者)

こんにちは、じゃんぬねっと です。

■No9601に返信(管理人さんの記事)
> この様にすると、Ctrl+C以外ではコピーできないことになりそうですが、
> 例えばCtrl+Shift+Cとしても通常はコピーできるでしょう。
> このように考えると、前者のような方法になると思うのですが。

何か「フレーム」みたいになってイヤなのですが、疑問点を残したくないので投稿します。

管理人さんの仰る通り、[Ctrl] + [C] の条件が揃っている状態ならば、
他の必要ないキーが付加されていても、コピーとして動作しないとまずいでしょう。

ですが、キャストは必要ないと思ったのです。
たとえば、以下のような実装では何か問題があるのでしょうか?
方法論の相違と言われれば、それまでになっちゃいますけど。



--- [VB.NET] ---------------------------------------------------

  Private Const WM_KEYDOWN As Integer = &H100

  Protected Overrides Function ProcessCmdKey( _
  ByRef msg As Message, ByVal keyData As Keys) As Boolean
    If msg.Msg = WM_KEYDOWN Then
      If (keyData And Keys.Control) = Keys.Control Then
        If (keyData And Keys.KeyCode) = Keys.C Then
          MessageBox.Show("コピーでっせー")
          Return True
        End If
      End If
    End If

    Return MyBase.ProcessCmdKey(msg, keyData)
  End Function

--- [C#] -------------------------------------------------------

  private const int WM_KEYDOWN = 0x100;

  protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
    if (msg.Msg == WM_KEYDOWN) {
      if ((keyData & Keys.Control) == Keys.Control) {
        if ((keyData & Keys.KeyCode) == Keys.C) {
          MessageBox.Show("コピーでっせー");
          return true;
        }
      }
    }

    return base.ProcessCmdKey (ref msg, keyData);
  }



# 関係ない話ですが、専用アイコンが使えなくなっちゃってます。
# http://dobon.net/cgi-bin/vbbbs/cbbs.cgi?mode=img
# なお、この 3 行は後ほど DELETE します。
2005/03/06(Sun) 04:51:02 編集(管理者)

> ですが、キャストは必要ないと思ったのです。

No9553 の投稿を読んだ人の中には、後者のようにOrを使う方が、前者のようにAndを使用するよりも良い方法だと誤解される方もいらっしゃるのではないかと思い、指摘させていただきました。それ以外の他意は一切ありません。誤解をされたようでしたら、申し訳ありませんでした。

> # 関係ない話ですが、専用アイコンが使えなくなっちゃってます。
> # http://dobon.net/cgi-bin/vbbbs/cbbs.cgi?mode=img
> # なお、この 3 行は後ほど DELETE します。

大変失礼しました。掲示板を改造して設定も変えてしまったようです。直しましたので、これまで通りお使いください。3行は削除しなくて結構です。

なお、「さま」はご遠慮ください。じゃんぬねっとさんを怒らせてしまったかと心配おります。
こんにちは、じゃんぬねっと です。

■No9623に返信(管理人さんの記事)
> 前者のようにAndを使用するよりも良い方法だと誤解される方もいらっしゃるのではないかと思い、指摘させていただきました。

あ、それについては了解しました。(^^)
正直、初めは色んな意味で誤解しておりました。

> それ以外の他意は一切ありません。
> 誤解をされたようでしたら、申し訳ありませんでした。

すいません、私の指摘の仕方がまずかったです。
元質問者さんのソースしか、目を通していなかったもので、
アンパサントの真意を知ったのは投稿した後でした。(^-^*)

> なお、「さま」はご遠慮ください。

すいません、素直な気持ちで「さま」と書かせて頂きました。
私は、どぼん!さんを尊敬申し上げておりますので... m(_ _)m

> じゃんぬねっとさんを怒らせてしまったかと心配おります。

いえいえ、とんでもないです。
元はと言えば、私の書き方に問題がありましたから...

コミュニケーションを通して、文章の書き方を学ぶ良い機会になったと思い、逆に感謝の気持ちでいっぱいです。
これからもよろしくお願いします。m(_ _)m
解決済み!
2005/03/07(Mon) 05:05:21 編集(管理者)

もうこのスレッドに返信すべきではないと思いましたが、最後に一言書かせてください。

このスレッドがこれだけ長くなってしまった原因を作ったのは No9403 の私の返信であり、この様に無責任な返信をしてしまったことを反省しています。また、そのためにじゃんぬねっとさんや多くの方に負担をかけてしまったことを申し訳なく思うとともに、最後までフォローしていただいたことを感謝いたします。

DOBON.NET | プログラミング道 | プログラミング掲示板