2017-06-16 1 views
0

私は複数のフォームを持つプロジェクトを持っています。これらのフォームの多くは、DataBoundアイテムを持つDataGridViewを持ち、クラスTicketのインスタンスにバインドされています。これらのすべてのDataGridViewに同じContextMenuを与えたいと思います。ユーザーがDataGridViewの行を右クリックし、コンテキストメニューの項目をクリックすると、データバインドTicketで処理する必要があります。別のフォームから継承したContextMenuサブメニューからDataGridViewのオブジェクトを取得します

これを達成するために、私は他のフォームから継承した基本フォームを作成しました。この塩基形態では、私はのContextMenuを定義した(私は前にコンテキストメニュー年代に働いていないので、試行錯誤だった、と私は、これはそれを行うための最善の方法であることを確認するために知りません。):

public ContextMenuStrip ContextTicket; 

public frmBaseForm() 
{ 
    InitializeComponent(); 
    ContextTicket = new ContextMenuStrip(); 

    var itemEdit = ContextTicket.Items.Add("Edit "); 
    itemEdit.Click += itemEdit_Click; 

    var itemAssign = ContextTicket.Items.Add("Assign to"); 

    foreach (var user in Selection.Users) 
    { 
     ToolStripItem item = (itemAssign as ToolStripMenuItem).DropDownItems.Add(user.Name); 
     item.Click += itemAssign_Click; 
    } 

    var itemSetToFixed = ContextTicket.Items.Add("Set Fixed"); 
    itemSetToFixed.Click += itemSetToFixed_Click; 
} 

アイデア:contextmenuには3つのmenuitemがあります。編集、固定と割り当ての設定割り当て項目にサブメニューがあり、これはSelectionインスタンスに格納されたusersで動的に埋められます。これらのメニューとサブメニューはすべて、基本形式を継承するフォームで完全に細かく作成されます。

私が働いてしまった「設定された固定」の項目の後ろの機能、私はそうのような関連Ticketを検索:

public void itemSetToFixed_Click(object sender, EventArgs e) 
{ 
    var ticket = getTicket(sender); 

    /* 
     Do something with Ticket 
    */ 
} 

private Ticket getTicket(object sender) 
{ 
    try 
    { 
     ToolStripItem clickedItem = sender as ToolStripItem; 

     ContextMenuStrip owner = clickedItem?.Owner as ContextMenuStrip; 
     DataGridView control = owner?.SourceControl as DataGridView;    

     var obj = control?.SelectedRows[0].DataBoundItem; 

     if (obj is Ticket) 
     { 
      return (Ticket)obj; 
     } 
     else 
     { 
      return null; 
     } 

    } 
    catch (Exception e) 
    { 
     MessageBox.Show("Error", "Unable to retrieve ticket information from selection."); 
     return null; 
    }  
} 

でも、私は、トラブルの割り当て項目のサブメニューのから選択Ticketを取得しています。私がサブメニューから来たとき、clickedItem.OwnerToolStripDropDownMenuであり、私はもはやDataGridViewレベルには達していないようです。

ContextMenuのサブメニューから、元のクリックされた行(つまり、Ticket)をDataGridViewで取得するにはどうすればよいですか?方法を聞いて、あなたのDataGridViewマウスのクリックイベントに

答えて

1

、DataGridViewのよう送信者を扱う:

private void DataGridViewMouseClick(object sender, MouseEventArgs e) 
{ 
    if (e.Button == MouseButtons.Right) 
    { 
     DataGridView dgv = sender as DataGridView; 
     if (dgv != null) 
     { 
      // find the current index 
      int currentIndex = dgv.CurrentRow.Index; 
      // find the current Ticket 
      Ticket currentTicket = dgv.CurrentRow.DataBoundItem as Ticket; 

      ContextMenu menu = new ContextMenu(); 
      // set up the context menu here... 
      menu.Show(dgv, new Point(e.X, e.Y)); 
     } 
    } 
} 

ご希望の場合はDGVとcurrentTicketオブジェクトは、別の方法を割り当てることができます。

DataGridView dgv = (DataGridView) sender; 
Ticket currentTicket = (Ticket) dgv.CurrentRow.DataBoundItem; 

として、現在のインデックスを見つけるまでは、このメソッドが適切に機能する前にユーザーが何かをクリックしていなければなりません...そこで、これが行われたことを確認するためにチェックを入れることが賢明でしょう。

うまくいけば、これが役に立ちます。

+0

よく見えます! gridviewイベントの使用を考えなかった。私は月曜日にそれをテストします。これはおそらく、私はグリッドビューの遺伝性を作る必要があることを意味しますね。彼らが同じ名前を持っていれば十分でしょうか? – HoneyBadger

+1

DataGridViewの名前は重要ではありません。しかし、何が重要かは、正しいマウスクリックイベントにメソッドを配線することです。そうしないと、適切なMouseEventArgsオブジェクトが作成されません(メニューの表示が難しくなります)。選択した場合、DataGridViewのそれぞれに対して同じイベント処理メソッドを使用することができます。この目的のために働くものは 'CellClick'イベントです。この作業を行うためにDataGridViewを編集する必要があるとは思いません。 – Sal

+0

そうですね。これまでのおかげで、私はそれを試してみることがあります。 – HoneyBadger

関連する問題