2011-01-25 4 views
2

BindingNavigator를 사용하여 datagridview를 통해 제품 목록에서 항목을 삭제합니다. (main.DeleteProduct() 메소드 호출은 데이터베이스에서 삭제할 저장소를 호출한다).올바른 항목이 아닌 BindingNavigator가있는 목록 항목을 삭제하십시오.

..DeleteItem_Click 이벤트의 코드를 향상시키는 데 도움이 필요합니다. 셀 또는 행을 클릭 한 다음 단추 (BindingNavigator)를 삭제하면 절대로 해당 행이 삭제되지 않습니다. 아래의 행을 삭제하거나, 마지막 행, 위의 행 및 하나의 행만 삭제하면 null이 캐스팅됩니다. bindingSource.Current가 datagridview의 currentrow와 같은 항목이어야합니까?

또한 바인딩 소스를 사용하여 현재 항목을 캐스팅하는 것이 좋은 방법입니까? 당신이 가진다면 더 나은 코드 제안을 appretiate 것입니다.

건배!

public partial class Form1 : Form 
{  
    private MainBL main = new MainBL(); 
    private List<Product> products = new List<Product> 

    private void Form1_Load(object sender, EventArgs e) 
    { 

     bsProducts.DataSource = products;   // BindingSource 
     bnProducts.BindingSource = bsProducts; // BindingNavigator 
     dataGridView1.DataSource = bsProducts; // 
    } 

    private void bindingNavigatorDeleteItem_Click(object sender, EventArgs e) 
    { 

     Product product = (Product)bsProducts.Current; 

     // Putting a breakpoint here, shows the identity property is not the same 
     // as row selected in datagridview. 

     main.DeleteProduct(product); 

    } 

답변

1

이제 CellClick 이벤트가 발생하기 전에 행이 삭제되었음을 알았습니다. 그래서 나는 삭제 단추의 _MouseDown 이벤트에 코드를 넣는 대신 의도 한대로 작동하게 만듭니다. 이

private void btnDeleteProducts_MouseDown(object sender, MouseEventArgs e) 
    { 
     Product product = (Product)bsProducts.Current; 
     if (product != null) 
     { 
      main.DeleteProduct(product); 
     }     
    } 
2

더 나은 솔루션은 아마도 바인딩 네비게이터의 삭제 이벤트를 삭제/차단하고, 수동으로 삭제를 처리하는 것입니다 ..하지만 가장 적절한 솔루션입니다 확실하지.

바인딩 네비게이터로 이동하십시오. 속성 창에서 속성을 불러옵니다. "Items"범주 아래에서 DeleteItem 속성을 찾아서 "none"으로 설정하십시오.

이제 관련 도구 모음의 삭제 버튼의 클릭 이벤트에서 삭제 기능을 코딩 할 수 있습니다. 이전 대답의 코드가 작동합니다. 이제 올바른 "현재"항목을 얻을 수 있습니다. 필요한 경우 여기에도 확인 확인 ("Are you sure?")을 추가 할 수 있습니다.

물론 BindingSource가 바인딩 된 컬렉션에서 항목을 제거하거나 데이터를 새로 고치는 것을 잊지 마십시오.

+0

... :

ClearCache()은 잘 알려진 DataContext에 확장 기능입니다 – ChenChi

0

나는 이것을 보았고 OP [bretddog]와 비슷한 것을했지만 나는 더 완벽한 방법을 썼다.

나는 여기에 내 작품을 공유

public class YourDataItem 
{ 
    // put all of your data here. This is just stubbed here as an example 
    public int Id { get; set; } 
    public String Description { get; set; } 
} 

private void DeleteBtn_Down(Object sender, MouseEventArgs e) 
{ 
    var item = (YourDataItem)bindingSource1.Current; 
    var dr = DialogResult.None; 
    if (0 < item.Id) 
    { 
     var ask = String.Format("Delete Item [{0}]?", item.Description); 
     dr = MessageBox.Show(ask, "Confirm Delete", MessageBoxButtons.YesNo, MessageBoxIcon.Question); 
    } 
    if (dr == DialogResult.Yes) 
    { 
     try 
     { 
      bindingSource1.EndEdit(); 
      _datamodel.YourDataItems.DeleteOnSubmit(item); 
      _datamodel.SubmitChanges(); 
      _datamodel.ClearCache(); 
      bindingSource1.SetPosition<YourDataItem>(x => x.Id == 0); 
     } catch (Exception err) 
     { 
      MessageBox.Show("Database changes failed to complete.", String.Format("Delete {0}", err.GetType()), MessageBoxButtons.OK, MessageBoxIcon.Information); 
     } 
    } else 
    { 
     bindingSource1.CancelEdit(); 
    } 
} 

의 LINQ 데이터 소스가 제한 시간을 초과 할 수 있습니다.

누군가가 집을 걷고있을 때 삭제 버튼을 누르면 확인 대화 상자에서 다음 날에 "확인"을 클릭하면 try...catch이 Object Disposed Exception을 처리합니다. 이 대답은 내가있는 DataGridView와의 deleteItem 기능을 가지고 같은 문제를 디버깅 나에게 도움이

/// <summary> 
/// Clears the cache from a DataContext to insure data is refreshed 
/// </summary> 
/// <param name="dc"></param> 
public static void ClearCache(this DataContext dc) 
{ 
    dc.GetType().InvokeMember("ClearCache", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, dc, null); 
} 
관련 문제