Удалить элемент списка с помощью BindingNavigator, а не правильный элемент

Я использую BindingNavigator для удаления элементов из списка продуктов через представление данных. (Вызов метода main.DeleteProduct() вызывает репозиторий для удаления из базы данных).

Мне нужна помощь, чтобы улучшить код события ..DeleteItem_Click. Когда я нажимаю ячейку/или строку, а затем кнопку удаления (BindingNavigator), она никогда не удаляет эту строку. Он удаляет строку ниже или, если это последняя строка, строку выше, а если только одну строку, приводится нуль. Разве BindingSource.Current не должен быть тем же элементом, что и currentrow в datagridview?

Кроме того, хорошо ли использовать текущий элемент с помощью источника привязки? Хотелось бы лучшего предложения кода, если оно у вас есть.

Ваше здоровье!

 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);

    }

person bretddog    schedule 25.01.2011    source источник


Ответы (3)


Лучшим решением, вероятно, является перехват/удаление события удаления Binding Navigator и обработка удаления вручную.

Перейти к Навигатору привязок; Поднимите свойства в окне свойств. Найдите свойство DeleteItem (в категории «Элементы») и установите для него значение «(нет)».

Теперь вы можете запрограммировать функцию удаления в событии нажатия кнопки удаления на соответствующей панели инструментов. Код в предыдущем ответе будет работать — теперь вы можете получить правильный «текущий» элемент. Вы также можете добавить проверку подтверждения («Вы уверены?») здесь, если это необходимо.

Разумеется, не забудьте удалить элемент из коллекции, к которому привязан BindingSource (или просто обновить данные).

person Andy Thomas    schedule 19.10.2012
comment
этот ответ помог мне отладить ту же проблему, что и с функцией DataGridView и DeleteItem... - person solujic; 29.08.2016

Теперь я понял, что строка удаляется до того, как сработает событие CellClick. Поэтому я заставляю его работать так, как задумано, вместо этого помещая код в событие _MouseDown кнопки удаления. Хотя не уверен, что это самое правильное решение...

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

Я наткнулся на это и сделал что-то похожее на то, что сделал 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.

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);
}
person jp2code    schedule 04.11.2016