WPF:保存更改变量

时间:2017-05-30 11:44:42

标签: c# wpf

我想将List<List<Button>> lloMatrix的当前状态保存在另一个变量List<List<Button>> lloMatrixCopy中,用它创建一个Frame(我写的一个类)并将其添加到列表loFrames中。 lloMatrixCopy作为框架的属性,之后不得更改。我尝试了不同的方法,但我的最终列表每次只列出相等的lloMatrixCopy,全部与最新版本的lloMatrix相同。 所以我的问题是如何制作lloMatrix当前状态的副本,而不会在lloMatrix更改后立即覆盖。

List<List<Button>> lloMatrixCopy = new List<List<Button>>;
List<List<Button>> lloMatrix = new List<List<Button>>;
List<Frame> loFrames = new List<Frame>;

//...
//lloMatrix gets filled with objects
//...

private void Btn_Click(object sender, RoutedEventArgs e)
{
   lloMatrixCopy = lloMatrix;
   var oNewFrame = new Frame(lloMatrixCopy);
   loFrames.Add(oNewFrame);
}

lloMatrix之后会发生变化,但是loFrames只会在按钮被按下的那一刻列出状态。我想这是一个简单的问题,但我尝试了许多事情而且它不起作用。也很抱歉没有完美的英语。我希望这是可以理解的。

编辑:感谢您快速回复,但出于某些原因

_lloMatrixCopy = _lloMatrixLeds.Select(original => original.ToList()).ToList();

也没有解决问题。这里是完整的Btn_Click() - 方法

private void Btn_Click(object sender, RoutedEventArgs e)
        {
            lloMatrixCopy = lloMatrix.Select(original => original.ToList()).ToList();
            var oNewFrame = new Frame(lloMatrixCopy);
            loFrames.Add(oNewFrame);

//After adding the copy to the list i want to put lloMatrix back in Default
//mode - which means in my case Change the Background Color of every Button to a specific Default
//Color. but the foreach-loop doenst only Change the lloMatrix, but also the
//copy, so that every Matrix saved in loFrames is a Default Matrix
// Globals.LClickedButtons is a list of every Button in lloMatrix which Background-Color
// isn't equal to the Default-Color
            foreach (var btn in Globals.LClickedButtons)
            {
                btn.Background = loLedColorBrushes[0];             
            }
        }

一旦foreach循环完成,loFrame中的每个矩阵仍然是默认矩阵。

3 个答案:

答案 0 :(得分:1)

这将进行深层复制

using System.Windows.Markup;
using System.Xml;
using System.IO;

T CloneXaml(T source){
    string xaml = XamlWriter.Save(T);
    using (StringReader stringReader = new StringReader(xaml))
    using (xmlReader = XmlReader.Create(stringReader))
        return (T)XamlReader.Load(xmlReader);
}


lloMatrixCopy = lloMatrix.Select( inner => inner.ToList().Select(CloneXaml)).ToList();

您需要了解List<T>reference type

  

C#中有两种类型:引用类型和值类型。   引用类型的变量存储对其数据(对象)的引用,   而值类型的变量直接包含它们的数据。同   引用类型,两个变量可以引用同一个对象;   因此,对一个变量的操作可能会影响引用的对象   由另一个变量。对于值类型,每个变量都有自己的变量   数据的副本,并且不可能对其进行操作   变量影响另一个(除了ref和out之外)   参数变量,参见ref和out参数修饰符)。

答案 1 :(得分:0)

lloMatrixCopy = lloMatrix; 

只需创建对列表中每个项目的第二个引用,这样如果您修改其中一个列表中的项目,另一个列表中的相应项目也会被修改。

您需要复制列表中的每个项目并将其放入第二个列表中。像这样的东西会起作用

lloMatrixCopy = lloMatrix.Select(original => original.ToList()).ToList();

答案 2 :(得分:0)

您需要克隆每个Button个元素。克隆WPF元素的最简单方法是使用此处建议的XamlWriter.SaveXamlReader.Load方法:

How can you clone a WPF object?

以下内容仅创建List<Button>的副本:

_lloMatrixCopy = _lloMatrixLeds.Select(original => original.ToList()).ToList();

两个列表仍将保留对同一Button个元素的引用。

所以你需要做这样的事情来克隆实际的Button元素:

foreach (var btn in Globals.LClickedButtons)
{
    string xaml = System.Windows.Markup.XamlWriter.Save(btn);

    using (System.IO.StringReader stringReader = new System.IO.StringReader(xaml))
    {
        using (System.Xml.XmlReader xmlReader = System.Xml.XmlReader.Create(stringReader))
        {
            Button newButton = (Button)System.Windows.Markup.XamlReader.Load(xmlReader);
            //...
        }
    }
}