Click here to Skip to main content
6,822,613 members and growing! (20,542 online)
Email Password   helpLost your password?
Desktop Development » Selection Controls » General     Beginner License: The Code Project Open License (CPOL)

RefEdit Emulation for .NET

By pablleaf

A simple implementation of a ref edit control for .NET
VB (VB9.0), .NET (.NET2.0), Office, Visual-Studio (VS2008), Dev
Revision:13 (See All)
Posted:29 Jan 2009
Updated:10 Feb 2009
Views:10,882
Bookmarked:16 times
Unedited contribution
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
7 votes for this article.
Popularity: 3.46 Rating: 4.10 out of 5

1

2
1 vote, 14.3%
3
3 votes, 42.9%
4
3 votes, 42.9%
5

Introduction  

When I originally posted this article it was simple Proof-Of-Concept article showing that a refedit control can be build to communicate between Excel and your .NET app. I spent some time this past week and developed a reusable UserControl.

To keep things fair, I want to say that not all the ideas in the control are mine. I found some useful tidbits here (MSDN Blog). Although this works, I could not get it to work in Excel 2003. Just changing the PIA references was not enough. It is tied to Office 2007 thru the RibbionUI.

After consolidating my work and using some of the techniques from the MSDN blog. I developed this UserControl that works with Excel 2003.

Example_1.png

Background

I started a project last year that required my .NET application to communicate with Excel. The project required that the user be able to select columns from a spreadsheet to be uploaded to SQL.

As everyone who has done Excel VBA programming, the refedit control is great! it allows users to select ranges from a spreadsheet thru the use of the mouse or keyboard.

With the introduction of .NET and VSTO, Microsoft did not release a refedit control. This meant that porting your beloved VBA code, that used a refedit control, to .NET was not going to happen so smoothly.

Like everyone else I hopped right onto Google's search engine and looked up RefEdit Controls for .NET. Guess what? Never found one and all the forums I visited said that Microsoft would not provide one because the RefEdit control is TIGHTLY integrated with Excel. All the examples I found said to us the InputBox. While this is a workaround, it shouldn't be the solution.

Using the Code

The user control consist of two components:

  1. Textbox
  2. Button

The user control also uses the 11.0 Interop assembly for Excel (Microsoft.Office.Interop.Excel)

Configuring the Control

After you have added the control to the toolbox. You simply drag it to any place on the form. At this time, the control is not functional it requires that you "connect" it to the spreadsheet it is talking to.

Me.Excel2003RefEdit1.Connection = xl

The connection property of the RefEdit control is of Type Excel.Application. This means that you will have to have the Excel Object instantiated on the form.

Dim xl As Microsoft.Office.Interop.Excel.Application

 Private Sub Form2_Shown(ByVal sender As Object,
     ByVal e As System.EventArgs) Handles Me.Shown

        xl = New Microsoft.Office.Interop.Excel.Application
        xl.Workbooks.Add()
        xl.Visible = True

        Me.Excel2003RefEdit1.Connection = xl
        Me.Excel2003RefEdit2.Connection = xl

 End Sub

At this point, this is all the configuration required for the control to work. The rest happens inside the control.

How does it capture the Cell Selection?

Once a "connection" has been established with the spreadsheet. The control is functional. For the control to capture the cell selection in Excel, I created a method that captures the Excel Event. This method is fired when the user selects the refedit control.

Private Sub SinkEvents()
    xlSheet = RefEditExcel.ActiveSheet
    EventDel_SelectionChange = New Excel.DocEvents_SelectionChangeEventHandler(
        AddressOf SelectionChange)
    AddHandler xlSheet.SelectionChange, EventDel_SelectionChange
End Sub

Private Sub txtAddress_Enter(ByVal sender As Object,
    ByVal e As System.EventArgs) Handles txtAddress.Enter
    Call SinkEvents()
End Sub

The method that captures the excel range writes the value to the textbox. It requires the use of a delegate because of Cross Threading.

Delegate Sub WriteData(ByVal value As String)

Private Sub SelectionChange(ByVal Target As Excel.Range)
    Call WriteHeader("'" & Target.Worksheet.Name & "'!" & Target.Address)
    Call NAR(Target)
End Sub

Private Sub WriteHeader(ByVal value As String)
    If Me.InvokeRequired Then
        Me.Invoke(New WriteData(AddressOf WriteHeader), New Object() {value})
    Else
        Me.txtAddress.Text = value
    End If
End Sub

Once the data is written, I make sure to destroy the Excel Reference. This is done using the NAR method.

Private Sub NAR(ByVal ComObj As Object)
    Try
        System.Runtime.InteropServices.Marshal.ReleaseComObject(ComObj)
        ComObj = Nothing

        GC.Collect()
        GC.WaitForPendingFinalizers()
    Catch ex As Runtime.InteropServices.COMException
        MessageBox.Show(ex.Message)
    End Try
End Sub

When the user clicks out of the control, the control releases its handle on the Excel Event.

Private Sub UnSinkEvents()
    RemoveHandler xlSheet.SelectionChange, EventDel_SelectionChange
End Sub

Private Sub txtAddress_Leave(ByVal sender As Object,
    ByVal e As System.EventArgs) Handles txtAddress.Leave
    Call UnSinkEvents()
End Sub

How do you Minimize/Maximize the control? 

Example_2.png 

The resizing of the control is done through the following method. It uses a structure to store the data and use.

Private Sub ResizeParent()

        For Each c As Control In ParentForm.Controls
            c.Visible = ControlDisplay.ParentMinimized
        Next

        Visible = True

        If Not ControlDisplay.ParentMinimized Then
            Me.btnState.Image = My.Resources.RefEdit1
            ControlDisplay.ParentClientSize = ParentForm.ClientSize
            ControlDisplay.ControlPrevX = Left
            ControlDisplay.ControlPrevY = Top
            ControlDisplay.ControlAnchor = Anchor

            Anchor = AnchorStyles.Left
            ParentForm.ClientSize = New Size(Me.Width, Me.Height)
            Left = 0
            Top = 0

            ControlDisplay.ParentPrevBorder = ParentForm.FormBorderStyle
            ParentForm.FormBorderStyle = FormBorderStyle.FixedDialog
            ControlDisplay.ParentControlBox = ParentForm.ControlBox
            ParentForm.ControlBox = False
        Else
            Me.btnState.Image = My.Resources.RefEdit0
            ParentForm.ClientSize = ControlDisplay.ParentClientSize
            Anchor = ControlDisplay.ControlAnchor
            Left = ControlDisplay.ControlPrevX
            Top = ControlDisplay.ControlPrevY
            ParentForm.FormBorderStyle = ControlDisplay.ParentPrevBorder
            ParentForm.ControlBox = ControlDisplay.ParentControlBox
        End If
    End Sub

The control can also be resized by using the keyboard shortcut (F4). One benefit that this keyboard shortcut has that the Excel refedit control does not have, is that the (F4) shortcut will resize in both directions. The Excel refedit only shrinks the control. This will Shrink and Grow.

Private Sub txtAddress_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtAddress.KeyDown
    If e.KeyCode = Keys.F4 Then
        Call DoResize() 'Method that calls the ResizeParent Method
    End If
End Sub

COM Object Management 

To make sure that the Excel.exe process can be killed when the application is closed. I make sure to release any COM objects that the control may be using. I manage this when the control is being disposed.

Private Sub RefEditControl_Disposed(ByVal sender As Object,
    ByVal e As System.EventArgs) Handles Me.Disposed
    Try
        If RefEditExcel IsNot Nothing Then
            RemoveHandler xlSheet.SelectionChange, EventDel_SelectionChange

            Call NAR(xlSheet)
            Call NAR(RefEditExcel)
            Call NAR(Connection)

            EventDel_SelectionChange = Nothing
            ControlDisplay = Nothing
        End If

    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try

End Sub

Points of Interest

You must also make sure that you dispose of the Excel COM objects used outside of the control.

I am sure there a some bugs that need to be addressed, and I will continue to improve this control. If you find anything, please advise on how you fixed it so that I can update the control.

History

  • v1.0 - Initial Release
  • v1.1 - Added Sample and Source code
  • v1.2 - Release of UserControl along with its supporting source code and examples.
  • v1.3 - Updated control to allow it to be stretched or shrunk.
  • v1.4 - Fixed:  A bug introduced when stretching or shrinking the control.
           - Added: The ability to minimize/maximize the control using the standard keyboard
                        shortcut (F4)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

pablleaf


Member
I am currently a .NET/Office VBA programmer. I also program in SQL Server. I also dipped my hand in languages such as java, coldfusion and even COBOL, but for now I am sticking with .NET.
Occupation: Software Developer
Location: United States United States

Other popular Selection Controls articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 9 of 9 (Total in Forum: 9) (Refresh)FirstPrevNext
GeneralStupid Question; how do I access the range value from within my code? Pinmemberrmorrow2:52 24 Nov '09  
GeneralRe: Stupid Question; how do I access the range value from within my code? Pinmemberssyladin20025:34 1 Dec '09  
QuestionRefEdit in an AddIn PinmemberPDTPGY0:31 15 May '09  
GeneralAnother Problem with this Control PinmemberAlexander Dickbauer22:05 1 Mar '09  
QuestionRe: Another Problem with this Control Pinmemberpablleaf4:43 2 Mar '09  
GeneralFound a Problem PinmemberAlexander Dickbauer21:34 1 Mar '09  
AnswerRe: Found a Problem Pinmemberpablleaf4:42 2 Mar '09  
GeneralExcel PM provides a RefEdit control PinmemberBill Seddon23:58 2 Feb '09  
GeneralRe: Excel PM provides a RefEdit control Pinmemberpablleaf4:42 3 Feb '09  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads.

PermaLink | Privacy | Terms of Use
Last Updated: 10 Feb 2009
Editor: Sean Ewington
Copyright 2009 by pablleaf
Everything else Copyright © CodeProject, 1999-2010
Web17 | Advertise on the Code Project