2015-06-01 2 views
2

Я использую DataGridView в WPF. В случае RowEditEnding я получаю старую строку (до редактирования заканчивается), а затем вызвать метод с помощью диспетчера, чтобы получить новую строку (после редактирования)Почему диспетчер ведет себя таким образом, когда я передаю параметр?

private void myGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e) 
{ 
    DataRowView oldRowView = e.Row.Item as DataRowView; 
    DataRow oldRow = oldRowView.Row; 
    //When I put a breakpoint before the dispatcher is called, oldRow has the old row values. 
    Dispatcher.BeginInvoke(new Action(() => OnRowEdit(oldRow, e)), System.Windows.Threading.DispatcherPriority.Background); 
    //I have now passed the old row to OnRowEdit 
} 

void OnRowEdit(DataRow oldRow, DataGridRowEditEndingEventArgs e) 
{ 
    //Here oldRow has new row values. 
} 

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

+0

Это, вероятно, связано с использованием вашего делегата действий и захвата переменной в методе. –

+0

Может быть. Все еще не понимаю, почему это происходит. На данный момент я использую глобальную переменную. – nan

+0

Я отредактировал ваш заголовок. Пожалуйста, смотрите: «Если вопросы включают« теги »в их названиях?] (Http://meta.stackexchange.com/questions/19190/), где консенсус« нет, они не должны ». –

ответ

1

Без a good, minimal, complete code example невозможно точно знать, в чем проблема в вашем сценарии. Здесь недостаточно контекста.

Но, скорее всего, вы просто сталкиваетесь с временной проблемой. То есть, делегат, вызываемый BeginInvoke(), выполняется асинхронно, с некоторым неопределенным позже. Поскольку он поставлен в очередь для выполнения, он почти наверняка будет выполнен после того, как произойдет обновление строки, поэтому вы увидите новые значения к моменту запуска вашего метода.

Возможные решения включают в себя:

  1. Используйте метод Invoke() вместо BeginInvoke(). Это выполняется синхронно, гарантируя, что объект строки не был изменен при вызове метода OnRowEdit().
  2. Если все, что вам нужно, это значения из строки, извлеките их во временный объект (например, новый массив) перед вызовом BeginInvoke() и передайте , что объект вместо самого объекта строки.
  3. Просто позвоните OnRowEdit() напрямую. Не имея полного примера кода, непонятно, почему вы используете BeginInvoke(); обычно действия редактирования пользователя происходят в потоке диспетчера, и поэтому можно напрямую обращаться к объектам пользовательского интерфейса, без необходимости звонить Invoke() или BeginInvoke(). Обратите внимание, что это практически тот же вариант, что и # 1 & hellip; возможно, использование Invoke() было бы лишним.

Если ни один из перечисленных выше вариантов не работает для вас, пожалуйста, улучшить вопрос, в том числе хороший пример кода, объясняя, почему вы используете BeginInvoke() в первую очередь, и почему ни одно из этих предложений не работать в вашем случае.

+0

Спасибо за ваши предложения. Мне нужны значения старой строки, а также новые значения строк. Я могу легко получить новые значения строк в делегате, вызванном BeginInvoke(). Именно по этой причине я сначала храню старые значения строк перед вызовом BeginInvoke(). Я попытаюсь использовать массив для хранения значений. Сообщите, если это сработает. – nan

+0

Код, который вы показали, не хранит значения старой строки. Он просто сохраняет ссылку на объект строки. Без надлежащего примера кода я не могу сказать точно.Но я буду держать пари в вашем 'OnRowEdit()' методе, выражение 'object.ReferenceEquals (oldRow, ((DataRowView) e.Row.Item) .Row)' будет возвращать 'true'. Почему вы даже используете 'BeginInvoke()'? Это лежит в основе ваших проблем (не считая возможности использования модели представления для оповещения о смене данных). –

+0

Получил это. Благодарю. – nan

0

Что Питер Дунихо ответил на ваш точный вопрос. Но «правильным» способом сделать это, на мой взгляд, было бы использование ViewModel. Тогда у вас будет копия «старого» и может подтвердить «новое», которое решит вашу проблему (я думаю?). У вас будет гораздо больше общего контроля над тем, что происходит, и есть много других преимуществ для MVVM.