2011-01-25 14 views
2

BindingNavigatorを使用して、DataListViewを使用して商品リストからアイテムを削除します。 (メソッド呼び出しmain.DeleteProduct()はデータベースから削除するリポジトリを呼び出します)。リストアイテムをBindingNavigatorで削除します。正しいアイテムではありません。

..DeleteItem_Clickイベントのコードを改善するには、何か助けが必要です。セルまたは行をクリックしてから、ボタン(BindingNavigator)を削除すると、その行は削除されません。下の行を削除するか、最後の行であれば上の行になり、1行だけであれば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

より良い解決策は、おそらくバインディングNavigatorの削除イベントを削除/インターセプトすると、手動で削除を処理するために..ですけれども、最も適切な解決策であるかどうかわかりません。

バインディングナビゲータに移動します。プロパティウィンドウでプロパティを表示します。 "Items"カテゴリの下にあるDeleteItemプロパティを探し、 "(none)"に設定します。

これで、関連するツールバーの削除ボタンのクリックイベントで削除機能をコーディングできます。前の回答のコードがうまくいきます - 正しい「現在の」アイテムを取得できるようになりました。必要に応じて、確認のチェックを追加することもできます(「よろしいですか?」)。

もちろん、BindingSourceがバインドされているコレクションからアイテムを削除する(またはデータを更新する)ことを忘れないでください。

+0

この答えは、私はDataGridViewのとDeleteItem機能を持っていた同じ問題をデバッグする私を助けました... – 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のデータソースがタイムアウトすることができます。

翌日に帰宅中に誰かが削除ボタンを押して確認ダイアログボックスで[OK]をクリックすると、try...catchがオブジェクト廃棄例外を処理します。

ClearCache()はちょうどよく知られたDataContextの拡張です:

/// <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); 
} 
関連する問題