Pull to refresh

Comments 19

UFO landed and left these words here
Он не использует несколько потоков, он иногда использует «отложенные» вызовы (Dispatcher.BeginInvoke).
Впрочем, речь тут вообще не о нем :)
Похоже, DataBind так и остается больным, и его никогда не вылечат — по крайней мере, в родных компонентах .net.
Капитан Очевидность как бы говорит Вам:

DataGrid + BindingListCollectionView + DataView = DataBind

Вы статью-то читали, Капитан? В частности, пример, демонстрирующий баг на «голом» DataTable.
Не начинайте; я не Капитан :)

Дело не в «баге» DataTable. Дело в том, что транзакционность редактирования строки в таблице выполнена в лоб — создаем копию, и потом ее накатываем на основные данные либо отбрасываем. А грид (вернее, строка грида) делает байнд на эту временную копию. Все это вы и сами рассказали. Имхо, это — тупит датабайнд.

Интересно, насколько операции CurrencyManager (например, EndCurrentEdit) спасли бы положение.
> А грид (вернее, строка грида) делает байнд на эту временную копию.
Да даже если никто не байндится на строку, все равно оно неправильно работает.

> Имхо, это — тупит датабайнд.
Он не тупит, он честно взаимодействует с источником, не вдаваясь в подробности его реализации. Просто корявая реализация источника дала побочный эффект на конкретном контроле.
Под Mono бага нет :)

/usr/bin/gmcs --version
Mono C# compiler version 2.0.1.0

Проверял так:
using System;
using System.Data;
using System.Collections;
using NUnit.Framework;

namespace TestDataGridBug
{
           
    [TestFixture()]
    public class TestDataGridBug
    {
        
        [Test()]
        public void TestBugWithEditingRow()
        {
            var dataTable = new DataTable();
            dataTable.Columns.Add("Id", typeof (int));
            dataTable.Columns.Add("Name", typeof (string));

            var row = dataTable.NewRow();
            row["Id"] = 1;
            row["Name"] = "John";
            dataTable.Rows.Add(row);

            row = dataTable.NewRow();
            row["Id"] = 2;
            row["Name"] = "Jack";
            dataTable.Rows.Add(row);

            var view = dataTable.DefaultView;

            row.BeginEdit();
  
            Assert.AreEqual(0, ((IList)view).IndexOf(view[0]));
            Assert.AreEqual(1, ((IList)view).IndexOf(view[1]));
        }

        [Test()]
        public void TestBugWithoutEditingRow()
        {
            var dataTable = new DataTable();
            dataTable.Columns.Add("Id", typeof (int));
            dataTable.Columns.Add("Name", typeof (string));

            var row = dataTable.NewRow();
            row["Id"] = 1;
            row["Name"] = "John";
            dataTable.Rows.Add(row);

            row = dataTable.NewRow();
            row["Id"] = 2;
            row["Name"] = "Jack";
            dataTable.Rows.Add(row);

            var view = dataTable.DefaultView;

            //row.BeginEdit();
  
            Assert.AreEqual(0, ((IList)view).IndexOf(view[0]));
            Assert.AreEqual(1, ((IList)view).IndexOf(view[1]));
        }
    }
}

Вы «var» использовали только для примера или вы его и в «жизни» используете?
Использую и в жизни, когда это не ухудшает читабельность кода. А что?
Я бы сказал, что она страдает в основном тогда, когда переменной присваивается результат какой-то неочевидной функции.
В остальных случаях, как правило, все прозрачно.
Надо попробовать контролы из этого набора. А датагрид один классный недавно нашел на XCeed DataGrid Intro. Очень много функционала, но, к сожалению, коммерческий (для бесплатного использования только express edition).
Only those users with full accounts are able to leave comments. Log in, please.