2017-05-30 89 views
1

我想將List<List<Button>> lloMatrix的當前狀態保存在其他變量List<List<Button>> lloMatrixCopy中,創建一個Frame(我寫的一個類)並將它添加到列表loFrames。作爲幀的屬性,lloMatrixCopy不得在之後改變。我嘗試了不同的方式,但是我的最終列表每次只列出相同的lloMatrixCopy,全部相同於最新版本lloMatrix。 所以我的問題是如何做lloMatrix的當前狀態的副本,而不會在lloMatrix發生變化後立即被覆蓋。WPF:保存變量變量的當前值

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];    
      } 
     } 

每個Matrix在loFrames仍然是儘快的foreach循環默認矩陣完成。

+0

你更新'lloMatrix'與狀態值? –

+0

對不起,我不太清楚你的意思,我在做完副本後將'lloMatrix'更新並添加到列表中。請查看已編輯的問題 – Kunibert

+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參數修飾符) 。

+0

感謝您的快速回答!由於某些原因,它仍然無法正常工作。你可以看看我編輯的問題嗎? – Kunibert

+0

它將自己創建* list *的副本,但不會在列表中創建Button元素的副本。 – mm8

+0

確定已更新以克隆按鈕。 – bradgonesurfing

0

lloMatrixCopy = lloMatrix; 

,所以如果你在其他列表中的相應項被修改過的列表中的一個更改的項目,只需創建一個第二參考列表中的每個項目。

您需要複製列表中的每個項目並將其放入第二個列表中。像這樣將工作

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

感謝您的快速答案!由於某些原因,它仍然無法正常工作。你可以看看我編輯的問題嗎? – Kunibert

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); 
      //... 
     } 
    } 
}