2013-03-11 9 views
6

Winforms becerilerim biraz paslı. DataGridView için BindingSource kullanıyorum. DataGridView'un KeyDown numaralı sayfasında, istediğiniz gibi çalışan bir sonraki/bir önceki kaydı seçmek istiyorum.BindingSource MoveFirst/MoveLast çalışmıyor

Kullanıcı, son öğe seçildiğinde Keys.Down sonucuna ulaşırsa ilk seçmeyi ve ilk öğe seçildiğinde Keys.Up sonucunu seçerse sonuncuyu seçmek istiyorum. Ama o zaman hiçbir şey olmaz. bs.MoveFirst()/bs.MoveLast() doğru denir ama hiçbir şey olmuyor olduğunu

private void Grid_Keydown(Object sender, KeyEventArgs e) 
{ 
    if (e.KeyCode == Keys.Up) 
     previousItem(); 
    else if (e.KeyCode == Keys.Down) 
     nextItem(); 
} 

private void previousItem() 
{ 
    BindingSource bs = null; 
    switch (this.Type) // a custom enum 
    { 
     case AdminType.Channel: 
      bs = channelBindingSource; 
      break; 
     default: 
      break; 
    } 
    if (bs.Position - 1 < 0) 
     bs.MoveLast(); 
    else 
     bs.MovePrevious(); 
} 

private void nextItem() 
{ 
    BindingSource bs = null; 
    switch (this.Type) 
    { 
     case AdminType.Channel: 
      bs = channelBindingSource; 
      break; 
     default: 
      break; 
    } 
    if (bs.Position + 1 >= bs.Count) 
     bs.MoveFirst(); 
    else 
     bs.MoveNext(); 
} 

Not:

İşte kod.

Düzenleme: İlginç, beklendiği gibi ben bir düğmeden bu tetiklemek zaman çalışır (önceki/sonraki) yerine DataGridView 'ın OnKeyDown, herhangi bir fikir?

+0

bs.EndEdit(); moveFirst/Last? – NDJ

+0

@NDJ'den sonra şunu deneyebilir misiniz: Teşekkürler, ama işe yaramıyor. –

+0

belki de ızgaradaki bir şey bs konumunu geçersiz kılar. "KeyUp" gibi bir "daha sonra" olayını kullanmayı deneyin. –

cevap

2

Izgara, yukarı ve aşağı hareket ettiğinizde, altta yatan bağlama kaynağının konumunu otomatik olarak hareket ettirir.

Seçimin yukarıdan aşağıya doğru gidip gelmesini isterseniz tam tersi - grid_KeyDown olayını kontrol edebilirsiniz. Maalesef posistion'u hareket ettirmeyi denerseniz, gridview'in Row_Enter Etkinliği tarafından geçersiz kılınır. Böylece bağlama kaynak pozisyonunu değiştirir.

Grid_Keyup olayında, konum önceden ayarlanmış olduğundan, kullanıcının satırda hareket edip etmediğini veya satırdan uzaklaşmak isteyip istemediğini bilmezsiniz. Ama bindingSource.Position'u ayarlayan aslında işe yarar - ve ızgara tarafından geçersiz kılmıyor.

Ayrıca DataGridViewRow.Selected = true kullanabilirsiniz, ancak onun temel bağlama kaynağının konumunu taşımaz. Ayrıca multiselect'in etkin olduğu ızgaralar için ideal değildir.

Çirkin gerçek şu ki, satırının atlayıp atlamamasını kontrol etmek için bir boolean (kendi cevabını yaptığınız gibi) kullanmanız gerekir.Eğer PositionChanged etkinlikten kontrol etmek gerekmez ancak :(

, sadece grid_Keydown olayı handeling alarak yapabilirsiniz. Anladım edebileceği için bu kadar temiz

private bool _changePost; 
    private void dataGridView1_KeyUp(object sender, KeyEventArgs e) 
    { 
     var view = sender as DataGridView; 
     var bs = bindingSource1; 

     if (e.KeyData == Keys.Up) 
     { 
      if (bs.Position == 0 && _changePost) 
      { 
       _changePost = false; 
       bs.MoveLast(); 
      } 
      if (bs.Position == 0 && !_changePost) 
       _changePost = true; 

     } 
     else if (e.KeyData == Keys.Down) 
     { 
      if (bs.Position == bs.Count - 1 && _changePost) 
      { 
       bs.MoveFirst(); 
       _changePost = false; 
      } 
      if (bs.Position == bs.Count - 1 && !_changePost) 
       _changePost = true; 
     } 
    } 

+0

Yardımlarınız için teşekkürler. Bu çirkin değişken olmadan bir yaklaşımın olmaması çok kötü :) –

2

Jens Kloster'e teşekkürler, bu geçici çözümü buldum. Daha önce de belirttiği gibi, DataGridView zaten BindingSource pozisyonunun hareketini destekliyor. Yani odaklanmışsa ve yukarı/aşağı okla vurursanız, BindingSource 'MoveNext/MovePrevious örtük olarak adlandırılır.

Seçili öğenin, KeyUp olayını (daha sonra KeyDown olayı) ele aldığımda, biri programlı ve diğeri yerleşik hareket için kullandığında iki konumun "atladığını" fark ettim.

Sadece yukarı/aşağı tuşlarına basılırsa, konumu ilkden sonuncuya doğru hareket ettirmenin bir yolunu bulmam gerekiyor. bu biraz hantal ve hata eğilimli olduğundan

bool positionChanged = false; 
private void Source_PositionChanged(object sender, EventArgs e) 
{ 
    positionChanged = true; 
} 

private void Grid_KeyUp(Object sender, KeyEventArgs e) 
{ 
    if (e.KeyCode == Keys.Up) 
     previousItem(); 
    else if (e.KeyCode == Keys.Down) 
     nextItem(); 

    positionChanged = false; 
} 

private void previousItem() 
{ 
    BindingSource bs = null; 
    switch (this.Type) 
    { 
     case AdminType.Channel: 
      bs = channelBindingSource; 
      break; 
     default: 
      break; 
    } 
    if (!positionChanged && bs.Position == 0) 
     bs.MoveLast(); 
    else if (!positionChanged) 
     bs.MovePrevious(); 
} 

private void nextItem() 
{ 
    BindingSource bs = null; 
    switch (this.Type) 
    { 
     case AdminType.Channel: 
      bs = channelBindingSource; 
      break; 
     default: 
      break; 
    } 
    if (!positionChanged && bs.Position == bs.Count - 1) 
     bs.MoveFirst(); 
    else if (!positionChanged) 
     bs.MoveNext(); 
} 

Hala daha iyi çözümler için açığım: Bu nedenle ben sonradan kontrol edebilirsiniz bir bool değişken ayarlamak için BindingSource.PositionChanged olayı ele vardır.