Reputation: 126
I am developing an add-in for OneNote.
In the sinppet below, a global variable AllPageXML
is claimed first.
Then the very first time when a window is loaded, AllPageXML
is initinized with a value.
After that, the value of AllPageXML
is supposed to not be changed.
When the user input some keywords in a textbox, search in AllPageXML
will be excuted.
And AllPageXML
will be passed to an function FilterXml
. After returnning, the value of AllPageXML
has been changed.
How can I do to keep the value of AllPageXML
not changed? Any comments will be appreciated.
internal partial class NaviPages : LocalizableForm
{
public XElement AllPageXML;
public NaviPages()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
using var one = new OneNote();
var AllPageXML = one.GetAllPages();
//...//
}
private void tBoxKw_TextChanged(object sender, EventArgs e)
{
try
{
string strKeyWords = tBoxKw.Text.ToLower();
FilteredPageXml = FilterXml(AllPageXML, strKeyWords);
}
catch
{
MessageBox.Show("Failed to filter!");
}
}
public XElement FilterXml(XElement inXML, string strKeyWords)
{
string strSecKw, strPageKw;
XElement root = inXML;
///...///
//delete empty notebook
foreach (var child1 in root.Elements().Reverse())
{
if (!child1.HasElements) child1.Remove();
}
return root;
}
}
Also, I've tried to use the ICloneable
class to clone the AllPageXML
before using it.
namespace OneNoteAddIn
{
internal partial class NaviPages : LocalizableForm
{
public NaviPages()
{
InitializeComponent();
}
public MyPages xml1;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
using var one = new OneNote();
xml1= new MyPages();
xml1.AllPageXML= one.GetAllPages();
}
public XElement FilterXml(XElement inXML, string strKeyWords)
{
XElement root = inXML; // xml2.AllPageXML;
//delete empty notebook
foreach (var child1 in root.Elements().Reverse())
{
if (!child1.HasElements) child1.Remove();
}
return root;
}
private void tBoxKw_TextChanged(object sender, EventArgs e)
{
XElement FilteredPageXml;
MyPages xml2 = new MyPages();
xml2 = (MyPages)xml1.Clone();
XElement AllPageXML1 = xml2.AllPageXML;
try
{
string strKeyWords = tBoxKw.Text.ToLower();
FilteredPageXml = FilterXml(AllPageXML1, strKeyWords);
}
catch
{
MessageBox.Show("Failed to filter!");
}
}
}
class MyPages : ICloneable
{
public XElement AllPageXML;
public object Clone()
{
return this.MemberwiseClone();
}
}
}
Upvotes: 0
Views: 77
Reputation: 55
The line XElement root = inXML;
does not create a new object, it only sets the reference of root
to the same reference inXML
uses. So any changes to root
or inXML
will change the same object in memory. You should instead clone the object (create a new one with the same values). This can be done in 2 places.
FilterXml
method.tBoxKw_TextChanged
before FilterXml
is called and pass FilterXml
the clone.To clone an object you should create a new object (using new XElement()
) and set the properties of that element to the values of properties of the object you wish to clone (AllPageXML
). You could look into the ICloneable
interface: https://learn.microsoft.com/en-us/dotnet/api/system.icloneable.clone?view=net-7.0
Upvotes: 2