Windows Develop Bookmark and Share   
 index > Windows Forms Designer > How can a group of changes be merged into a single undoable action in the VS designer?
 

How can a group of changes be merged into a single undoable action in the VS designer?

This is related to the post @ http://social.msdn.microsoft.com/Forums/en-US/winformsdesigner/thread/bda84c83-d82a-4992-b2c1-13a4bc4660c7.

I have been creating a databound ListView and I have been enhancing it to support more of the design-time features available in Visual Studio.

The latest addition: A method that automatically adds column headers to the ListView control based on the properties exposed by the databound objects. The code is really simple, and is shown below:

        public void GenerateColumnsForDataSource()
        {
            CurrencyManager cm = (CurrencyManager)_lv.Parent.BindingContext[_lv.DataSource, _lv.DataMember];
            PropertyDescriptorCollection props = cm.GetItemProperties();
            foreach (PropertyDescriptor pd in props)
            {
                DataBoundListView.DataBoundColumnHeader header = _hostSvc.CreateComponent(typeof(DataBoundListView.DataBoundColumnHeader),
                    String.Format("dbch_{0}", pd.Name)) as DataBoundListView.DataBoundColumnHeader;
                GetPD(header, "DataField").SetValue(header, pd.Name);
                GetPD(header, "Text").SetValue(header, pd.DisplayName);
                _lv.Columns.Add(header);
            }
            GetPD(this.Component, "View").SetValue(this.Component, View.Details);
            _lv.Bind();
        }

This code uses the designer host to create each column header (because column headers are components), and then uses property descriptors to set the different column header properties. The last step is to force the binding process in order to refresh the view.

This code properly generates undo entries. But, it generates one undo entry for each single action. To clarify the picture here, note that each generated column generates 3 undo entries: One for the addition of the column, and then one for the DataField property and one for the Text property.

The question is: How can I force the Visual Studio designer to merge all these actions into a single, undoable action so the developer doesn't have to undo each of the steps?

Thank you all!
MCP
webJose  Monday, September 28, 2009 3:15 PM
Nevermind, I got it.

The designer provides transactions. Transactions can be named. Also, transactions encapsulate a group of actions together. The end result: A single "action" that describes and undoes everything in one go. Below is the updated code:

        public void GenerateColumnsForDataSource()
        {
            CurrencyManager cm = (CurrencyManager)_lv.Parent.BindingContext[_lv.DataSource, _lv.DataMember];
            PropertyDescriptorCollection props = cm.GetItemProperties();
            DesignerTransaction txn = _hostSvc.CreateTransaction("Automatic column header generation");
            try
            {
                foreach (PropertyDescriptor pd in props)
                {
                    DataBoundListView.DataBoundColumnHeader header = _hostSvc.CreateComponent(typeof(DataBoundListView.DataBoundColumnHeader))
                        as DataBoundListView.DataBoundColumnHeader;
                    GetPD(header, "DataField").SetValue(header, pd.Name);
                    GetPD(header, "Text").SetValue(header, pd.DisplayName);
                    _lv.Columns.Add(header);
                }
                GetPD(this.Component, "View").SetValue(this.Component, View.Details);
                _lv.Bind();
            }
            catch (Exception ex)
            {
                MessageBox.Show(String.Format("The operation raised an exception and was aborted.\n\nDescription:\n{0}",
                    ex.Message), "DataBoundListView Designer", MessageBoxButtons.OK, MessageBoxIcon.Error);
                txn.Cancel();
            }
            txn.Commit();
        }

MCP
  • Marked As Answer bywebJose Monday, September 28, 2009 4:43 PM
  •  
webJose  Monday, September 28, 2009 4:42 PM
Nevermind, I got it.

The designer provides transactions. Transactions can be named. Also, transactions encapsulate a group of actions together. The end result: A single "action" that describes and undoes everything in one go. Below is the updated code:

        public void GenerateColumnsForDataSource()
        {
            CurrencyManager cm = (CurrencyManager)_lv.Parent.BindingContext[_lv.DataSource, _lv.DataMember];
            PropertyDescriptorCollection props = cm.GetItemProperties();
            DesignerTransaction txn = _hostSvc.CreateTransaction("Automatic column header generation");
            try
            {
                foreach (PropertyDescriptor pd in props)
                {
                    DataBoundListView.DataBoundColumnHeader header = _hostSvc.CreateComponent(typeof(DataBoundListView.DataBoundColumnHeader))
                        as DataBoundListView.DataBoundColumnHeader;
                    GetPD(header, "DataField").SetValue(header, pd.Name);
                    GetPD(header, "Text").SetValue(header, pd.DisplayName);
                    _lv.Columns.Add(header);
                }
                GetPD(this.Component, "View").SetValue(this.Component, View.Details);
                _lv.Bind();
            }
            catch (Exception ex)
            {
                MessageBox.Show(String.Format("The operation raised an exception and was aborted.\n\nDescription:\n{0}",
                    ex.Message), "DataBoundListView Designer", MessageBoxButtons.OK, MessageBoxIcon.Error);
                txn.Cancel();
            }
            txn.Commit();
        }

MCP
  • Marked As Answer bywebJose Monday, September 28, 2009 4:43 PM
  •  
webJose  Monday, September 28, 2009 4:42 PM

You can use google to search for other answers

Custom Search

More Threads

• Custom property editor from external assembly
• Making a .net Grid
• Designer error since using VSS
• Problems with Painting a circle UserControl.
• Hosting Windows Form Desginers
• How to detect tab selection changed event in TabControl
• Events for ComboBox thats inside a dataGridView
• How to add a user control inside a treeview control as a node
• How to set readonly for property with return value of collection.
• Which Components and Controls can be used as MDIParent??