Search code examples
asp.netvb.netdictionarytextboxshallow-copy

VB .NET Textbox Shallow Copy into Dictionary


While there are many questions about shallow copy vs. deep copy, I couldn't find one specific to TextBoxes and Dictionaries in VB .NET. I believe my problem is unique enough to deserve it's own thread.

In VB .NET I am trying to implement a dictionary that links an internal class called PageDisplayFields.DisplayField that is essentially an Enum to TextBoxes. The key is the Enum and the value is the System.Web.UI.WebControls.TextBox. My issue is that I'd like to then be able to change the .Text of the TextBox in the dictionary and have it also change the .Text property of the TextBox originally input into the Dictionary. When the TextBox is added to the dictionary, it appears to be a deep copy, and not a shallow copy. Changes to the .Text property of either the original TextBox or the copy in the Dictionary do not pass through to one another.

Here's a code sample of what I'm trying to do:

Private Shared _TxtBoxLookup As New Dictionary(Of PageDisplayFields.DisplayFields, System.Web.UI.WebControls.TextBox)
Private Sub SetTxtBoxLookup()
    _TxtBoxLookup.Add(PageDisplayFields.DisplayFields.A, txtA)
    _TxtBoxLookup.Add(PageDisplayFields.DisplayFields.B, txtB)
    _TxtBoxLookup.Add(PageDisplayFields.DisplayFields.C, txtC)
    _TxtBoxLookup.Add(PageDisplayFields.DisplayFields.D, txtD)
    _TxtBoxLookup.Add(PageDisplayFields.DisplayFields.E, txtE)
End Sub

SetTxtBoxLookup() is called at the correct point only once, and doesn't have any errors. The structure of the _TextBoxLookup is never modified after this call.

If _TxtBoxLookup.ContainsKey(PageDisplayFields.DisplayFields.A) Then
    _TxtBoxLookup.Item(PageDisplayFields.DisplayFields.A).Text = "ThisText"
End If

If this code is called, _TxtBoxLookup.Item(PageDisplayFields.DisplayFields.A).Text is actually set to "ThisText". However, txtA.Text = "" (the default value).

Similarly, if I do the reverse operation, the same effect is observed:

ModHashTable("A") = _TxtBoxLookup.Item(PageDIsplayFields.DisplayFields.A).Text
'Assume "A" is the correct key to ModHashTable

If "3" is entered into the TextBox, txtA, ModHashTable("A") will be set to "" as this is still the value that _TxtBoxLookup.Item(PageDisplayFields.DisplayFields.A).Text has stored.

If I implement storage and retrieval by directly referencing the TextBoxes, everything works as expected, so I'm 99% sure that the problem in my code is that the TextBoxes aren't shallow copying, but are deep copying. Using dictionaries in this way let's me drastically reduce the length of many methods.

Is there a way to make the Dictionary store only references to the TextBoxes? An easy way to do a shallow copy?


Solution

  • This is ingenious, but it probably isn't going to work as written, because of how ASP.NET web pages work.

    Every time a page loads, all the controls on it are recreated and repopulated from ViewState. So, after postback, you may still have a shared Dictionary of controls ... but they are not the control objects that are currently on the page. They are the old ones.

    Now, you may still be able to make this work, as long as you re-load your dictionary with the controls at the beginning of the page lifecycle, such as in Page_Load.

    I would avoid using a shared Dictionary in any case, because it's going to be shared across all instances of the page. So two users accessing the same page will share the same dictionary, with potentially disastrous results.