【问题标题】:Variable changing, but I don't know where or why变量变化,但我不知道在哪里或为什么
【发布时间】:2014-05-21 16:16:55
【问题描述】:

我正在为我的 WPF 数据网格实现撤消功能,但是我遇到了问题。我确信这只是对 C# 语言及其语法的误解,但我不知道问题出在哪里。当单元格编辑结束时,我获取上一个项目并显示一个项目值 (Z)(用于调试目的)。它包含在编辑之前持有的项目(这是我想要的)。但是当我尝试“撤消”它时,我再次显示相同的值 (Z),但它已更改为数据网格中该项目的当前值。

CellEditEnding 处理程序

 private void toolGrid_CellEditEnding(object sender, DataGridVellEditEndingEventArgs e)
{
undoTool = toolsList[selectedToolNdx];
MessageBox.Show(undoTool.Z.ToString());
}

KeyDown 处理程序

private void toolGrid_PreviewKeyDown(object sender, KeyEventArgs e)
{
 if((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
 {
  if (e.Key == Key.Z)
   {
     MessageBox.Show(undoTool.Z.ToString());
     e.Handled = true;
   }
  }
 }

例如,我可以将 z 值从 3 更改为 5,并且 celleditending 事件会触发,并且消息框会显示值“3”(到目前为止一切正常)。但是,然后我撤消 (CTRL-Z) 并且消息框现在显示值“5”,即使它应该仍然是 3。为什么 undoTool 会发生变化(以及为什么它似乎会自行发生变化)?

【问题讨论】:

  • 这是 WPF DataGrid 预期行为的一部分。

标签: c# wpf datagrid


【解决方案1】:

问题在于,在“保存”旧值的同时,它会将自身保存为变量“undoTool”中的引用。因为它是一个引用,所以它不做任何其他事情,然后引用它的基础对象,这是您正在编辑的值。这意味着每当您更改基础对象时,对它的所有引用都将返回与您将其更改为相同的值。

您应该明确告诉 .NET 创建一个新对象,从而使用 new 关键字,然后将您的变量存储在其中。

【讨论】:

  • 很抱歉,我不知道新关键字的去向。我是否放了“undoTool = new ToolClass(); undoTool = toolsList[selectedToolNdx];”在单元格编辑结尾?
  • 我相信是的。另一种方法是在您的 ToolClass 中实现 ICloneable,然后使用 toolsList[selectedToolNdx].Clone()。你想保存整个对象还是只保存它的文本?因为如果要保存文本,最好使用字符串。
【解决方案2】:

由于您不知道在哪里或如何使用,因此您必须使用调试器或有权访问变量内存空间的线程。在调试器Add a watch and break on access / read write 的情况下,后者使用一个线程并休眠到something != somethingElse == true;,然后在调试之后执行逻辑。根据您在系统中的访问级别,您还可以使用一些鲜为人知的常量来确定函数调用和调用者。How to get the name of the current method from code

[CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)

您也可以使用Watch 窗口

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    • 2018-01-01
    相关资源
    最近更新 更多