C# PDA窗体重新打开后TextBox被释放的问题求助
Hey there! Let's break down what's going wrong here and fix that pesky bug step by step.
Root Cause Analysis
Your issue boils down to two key problems with resource cleanup and event handling:
- Uncleaned Event Subscriptions: You're binding the
OnScanevent to your barcode scanner in the form constructor, but never unbinding it when the form is disposed. The scanner object (likely a shared/global instance) still holds a reference to the old, disposed form's event handler. When you scan the second time, it triggers the old form's handler—where theTextBoxis already released. - Stale Static Context Reference: The
context = this;line (assumingcontextis a static variable) keeps pointing to the first form instance even after it's disposed. When you open a new form, the scan event still tries to use this dead reference.
Fix Steps
1. Properly Clean Up Barcode Scanner Events and Resources
Update your form's Dispose method to unbind the scan event and release the scanner resource:
protected override void Dispose(bool disposing) { if (disposing) { // Clean up barcode scanner resources first if (myBarcode2 != null) { // Unbind the event to break the reference to this form myBarcode2.OnScan -= myBarcode_OnScan; myBarcode2.Disable(); myBarcode2.Dispose(); myBarcode2 = null; } components?.Dispose(); } base.Dispose(disposing); }
2. Remove the Static context Variable
You don't need a static context—your scan handler is an instance method of the form, so you can directly use this to access current form controls:
void myBarcode_OnScan(ScanDataCollection sd) { // Use 'this' directly instead of a static context variable this.tbp1_1 = getTbl1_1(); // Example: Assign scanned data to the TextBox // if (sd?.Count > 0) this.tbp1_1.Text = sd[0].Data; }
Make sure getTbl1_1() is an instance method that returns the current form's TextBox (not a reference to an old, disposed one).
3. Optimize Scanner Lifecycle (Optional but Recommended)
Instead of initializing the scanner in the constructor, bind/unbind it when the form is activated/deactivated to ensure only the active form listens for scans:
protected override void OnActivated(EventArgs e) { base.OnActivated(e); if (AppCore.core.dispositivo_PDA && myBarcode2 == null) { myBarcode2 = new Barcode2(Devices.SupportedDevices[0]); myBarcode2.Enable(); myBarcode2.OnScan += myBarcode_OnScan; myBarcode2.Scan(); } } protected override void OnDeactivate(EventArgs e) { base.OnDeactivate(e); if (myBarcode2 != null) { myBarcode2.OnScan -= myBarcode_OnScan; myBarcode2.Disable(); myBarcode2.Dispose(); myBarcode2 = null; } }
4. Verify Form Creation Logic
Your current form creation code is okay, but just a quick note: ShowDialog() doesn't automatically dispose the form, so your manual form.Dispose() call is correct—this ensures the form's Dispose method runs to clean up resources.
FormAltaPalet form = new FormAltaPalet(Movements.AltaPalet); form.ShowDialog(); form.Dispose();
Final Notes
The core fix is ensuring you unbind events when disposing the form—this prevents stale references to disposed controls. Removing the static context variable eliminates another source of stale references. After these changes, your second form's scan event should correctly access its own, alive TextBox controls.
内容的提问来源于stack exchange,提问作者carmaikol

