Windows Develop Bookmark and Share   
 index > Windows Forms Designer > Preventing Undo Actions
 

Preventing Undo Actions

I need a way to prevent undo actions being added for changes that occour to my Root Control. The only way I have found to do this so far is to test if unit.Name.Contains("RootControl") in my AddUndoUnit function and ignore the unit. This works but is pretty weak and creates a problem if anyone uses the text 'RootControl' in the name of their control. (ie- such a control's undo actions will be ignored!).
A.J.Lawson  Monday, October 27, 2008 12:54 PM

Hi AJLawson

We have done some test on your case and found it was not easy to do. The only solution I have found was to control by its name from the unit.Name. The unit.Name is a string contains the operation and the control name. So I used the String.Split method to get the control name.

Code Snippet

[] s = unit.Name.Split(' ');

controlName = s[1];

The second string is the control name.

Then get the control by name.

Code Snippet

frm = new YourForm();

Control ctrl;

for (int i = 0; i < frm.Controls.Count; i++)

{

if (frm.Controls[i].Name == controlName)

{

ctrl = frm.Controls[i];

break;

}

}

(ctrl.Tag != null)

{

if (ctrl.Tag.ToString() == "RootControl")

{

return;

}

}

So you need to set the tag of the control to “RootControl�if this control is your root control. This solution seems not good enough, but it is the only one I can found till now.

Sincerely,

Kira Qian

Kira Qian  Thursday, October 30, 2008 4:53 AM
Hi Kira Qian,

Thanks for your solution, unfortunately it is very similar to my current solution but it's reassuring to see that I'm not missing something that's obviously better!

A potential problem occurs when creating custom transactions, grouping several actions together in a single undo unit. The transaction name you define becomes the unit.Name. This might not adhere to the convention of "[Action] [ControlName]" e.g. "Move MyControl1". I will just have to be careful not to create any transactions that breaks this convention, although it would be unlikely that I would create any transactions for the RootControl in my application, since I wish to ignore it.

I will use your method however because it is slightly better than mine in that it checks for the exact name "RootControl" not just if it contains that string. My approach led to a bug where any control who's name contained the text "RootControl" would be omitted from the undo stack.

Once again, thank you Smile
A.J.Lawson  Thursday, October 30, 2008 10:15 AM

Hi AJLawson

I want to know what is root control in your post? The name of each UndoUnit contain the string of the instance name and an operation type. I do not find any Root Control in my test. So please give me more information about it. Thank you!

Sincerely,

Kira Qian

Kira Qian  Wednesday, October 29, 2008 6:27 AM
Hi Kira Qian,

The root control in my post is actually a custom control I have created to use as the root for my designer. It takes the place of the more typical Form control and is more like a blank design canvas with an optional design grid. I add one of these to my design surface as the primary (root) control. My problem is that the UndoEngine is recording actions with this control such as adding it and resizing. I don't want these actions to be recorded for this control because it shouldn't be changed by the user, it is a part of the design environment, I only want the user to have control over the components placed onto this.
A.J.Lawson  Wednesday, October 29, 2008 9:48 AM

Hi AJLawson

We have done some test on your case and found it was not easy to do. The only solution I have found was to control by its name from the unit.Name. The unit.Name is a string contains the operation and the control name. So I used the String.Split method to get the control name.

Code Snippet

[] s = unit.Name.Split(' ');

controlName = s[1];

The second string is the control name.

Then get the control by name.

Code Snippet

frm = new YourForm();

Control ctrl;

for (int i = 0; i < frm.Controls.Count; i++)

{

if (frm.Controls[i].Name == controlName)

{

ctrl = frm.Controls[i];

break;

}

}

(ctrl.Tag != null)

{

if (ctrl.Tag.ToString() == "RootControl")

{

return;

}

}

So you need to set the tag of the control to “RootControl�if this control is your root control. This solution seems not good enough, but it is the only one I can found till now.

Sincerely,

Kira Qian

Kira Qian  Thursday, October 30, 2008 4:53 AM
Hi Kira Qian,

Thanks for your solution, unfortunately it is very similar to my current solution but it's reassuring to see that I'm not missing something that's obviously better!

A potential problem occurs when creating custom transactions, grouping several actions together in a single undo unit. The transaction name you define becomes the unit.Name. This might not adhere to the convention of "[Action] [ControlName]" e.g. "Move MyControl1". I will just have to be careful not to create any transactions that breaks this convention, although it would be unlikely that I would create any transactions for the RootControl in my application, since I wish to ignore it.

I will use your method however because it is slightly better than mine in that it checks for the exact name "RootControl" not just if it contains that string. My approach led to a bug where any control who's name contained the text "RootControl" would be omitted from the undo stack.

Once again, thank you Smile
A.J.Lawson  Thursday, October 30, 2008 10:15 AM

You can use google to search for other answers

Custom Search

More Threads

• DataGridView multiple display rows per one record
• Close image to delete
• TypeConverter
• Using Custom ProfessionalColor Table with toolstriprenderer.
• How to get user control from contextMenu.SourceControl
• Painting problem
• user control flickering - even using double buffer
• Image compression in compact framework
• designer reloads
• Panel Control