none
How to populate Word 2003 ComboBox / Dropdown list using VSTO C#

    Question

  • Hi,

    I am creating dynamic OLE Control ComboBox in Word 2003 using VSTO C#. After creating ComboBox I want to populate it with some values.

    If I use VBA then I can populate using following codelines.

    Dim myarray(3) As String
    myarray(0) = "US"
    myarray(1) = "AUS"
    myarray(2) = "UK"
    ComboBox1.List = myarray

    But in VSTO when I use following code lines:

    object objClass = "Forms.ComboBox.1";

    object objMissing = Type.Missing;

    Word.Shape myShape;

    myShape = Globals.ThisDocument.Shapes.AddOLEControl(ref objClass, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing);

    // OLE Control is a floating control on document. Embeded Control is not accepted.

    object[] Parameters = new Object[3];

    Parameters[0] = "US";

    Parameters[1] = "AUS";

    Parameters[2] = "UK";

    myShape.OLEFormat.Object.GetType().InvokeMember("List", System.Reflection.BindingFlags.SetProperty, null, myShape[1].OLEFormat.Object, Parameters);

    In this way it is not giving me any error and not even getting populated with 3 values. So I don't know how can I populate ComboBox / Dropdown list using VSTO C#?

    Thanks,

     

    Tuesday, June 20, 2006 9:17 AM

Answers

  • Well, the List property defines a two-dimensional array (row, column) for the list in the combobox. You define only one dimension. For one dimension, you should use the AddItem method; see the sample code at the end of my message.

    Note that you can place the combobox in-line with the text (probably what you mean by "embedded". Just create an InlineShape, rather than a Shape.

            private void CreateActiveXComboBox(string Name, object[] Items)
            {
                try
                {
                    Word.Range rng = this.InnerObject.Content;
                    object objRngEnd = Word.WdCollapseDirection.wdCollapseEnd;
                    rng.Collapse(ref objRngEnd);
                    object objRng = (object)rng;
                    object objClassType = "Forms.ComboBox.1";
                    object objControl;
                    objControl = (object) rng.InlineShapes.AddOLEControl(ref objClassType, ref objRng).OLEFormat.Object;
                    object[] objControlName = new object[1] { Name };
                    objControl.GetType().InvokeMember("Name", System.Reflection.BindingFlags.SetProperty, null, objControl, objControlName);
                     foreach (object item in Items)
                    {
                        object[] param = new object[1] { item };
                        objControl.GetType().InvokeMember("AddItem", System.Reflection.BindingFlags.InvokeMethod, null, objControl, param);
                    }
                }
                catch (SystemException ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }

    Tuesday, June 20, 2006 1:48 PM
    Moderator
  • Oh I Got it !!

    private void CreateControl()

    {

    object objClass = "Forms.ComboBox.1";

    object objMissing = missing;

    Word.Shape myCB;

    myCB = this.Application.ActiveDocument.Shapes.AddOLEControl(ref objClass, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing);

    myCB.OLEFormat.Object.GetType().InvokeMember("AddItem", System.Reflection.BindingFlags.InvokeMethod, null, myCB.OLEFormat.Object, new object[] { "US" });

    myCB.OLEFormat.Object.GetType().InvokeMember("AddItem", System.Reflection.BindingFlags.InvokeMethod, null, myCB.OLEFormat.Object, new object[] { "UK" });

    myCB.OLEFormat.Object.GetType().InvokeMember("AddItem", System.Reflection.BindingFlags.InvokeMethod, null, myCB.OLEFormat.Object, new object[] { "USA" });

    myCB.OLEFormat.Object.GetType().InvokeMember("Value", System.Reflection.BindingFlags.SetProperty, null, myCB.OLEFormat.Object, new object[] { "UK" });

    }

    Well Problem Solved. I was making two mistakes -1)  try to set "List" like in my this question put up VBA code line.  2) For "AddItem" I was using SetProperty instead of InvokeMethod.

    All well that ends well.

    I sincerely thank you for keeping in me in solution loop.

    Wednesday, June 21, 2006 12:49 PM
  • Hi Ramu

    I'm afraid using AddItem is the only way to add to the list of an ActiveX control. There's no way to pass an array, or a collection, or anything like that. You could put the list items into an array or collection then use a foreach loop with AddItem.

    Of course, if you're using VSTO (that is the topic of this forum, after all) there are alternatives to ActiveX controls...

    Wednesday, September 20, 2006 7:03 AM
    Moderator

All replies

  • Well, the List property defines a two-dimensional array (row, column) for the list in the combobox. You define only one dimension. For one dimension, you should use the AddItem method; see the sample code at the end of my message.

    Note that you can place the combobox in-line with the text (probably what you mean by "embedded". Just create an InlineShape, rather than a Shape.

            private void CreateActiveXComboBox(string Name, object[] Items)
            {
                try
                {
                    Word.Range rng = this.InnerObject.Content;
                    object objRngEnd = Word.WdCollapseDirection.wdCollapseEnd;
                    rng.Collapse(ref objRngEnd);
                    object objRng = (object)rng;
                    object objClassType = "Forms.ComboBox.1";
                    object objControl;
                    objControl = (object) rng.InlineShapes.AddOLEControl(ref objClassType, ref objRng).OLEFormat.Object;
                    object[] objControlName = new object[1] { Name };
                    objControl.GetType().InvokeMember("Name", System.Reflection.BindingFlags.SetProperty, null, objControl, objControlName);
                     foreach (object item in Items)
                    {
                        object[] param = new object[1] { item };
                        objControl.GetType().InvokeMember("AddItem", System.Reflection.BindingFlags.InvokeMethod, null, objControl, param);
                    }
                }
                catch (SystemException ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }

    Tuesday, June 20, 2006 1:48 PM
    Moderator
  • Actually I tried this method to embed control using InlineShapes and then populate it. But Embeded control is not allowed as per requirement. So I have added comment line that Floating control is accepted and embeded controls are not accepted.

     

     

    Wednesday, June 21, 2006 4:27 AM
  • My sample code using InlineShapes works here :-)

    FWIW, you shouldn't try to change ADDOLEControl to the "embed" type of control. That may be what's misleading you. Technically, the control is embedded in the Word document, no matter whether it's "floating" or "inline". The "embedded" control type is something else, not an ActiveX control like you're trying to use.

    Wednesday, June 21, 2006 8:48 AM
    Moderator
  • First of all let me Thank You for your keen interest and helping me.

    Let me explain "Embeded" and "Floating" with following para: 

    Requirement goes like this:

    There is one row in table. In this row I have to show different types of controls - Checkbox ( Multiple in single cell of row ), Option buttons (Multiple in single cell of row) and Combobox (Single in single row ) and also after selection of answer i have to delete controls also.

    If I use InLineShape object and AddOLEObject method - it is working fine with your posted sample code. But here requirement is very typical. As I have added InLineShapes like Multiple Check Box ( Say  3: US UK AUS) it increases row height for which I have used cell range to create these 3 object. So alternative is I can use shape object instead of InLineShapes then also AddOLEObject can work and I can add 3 checkbox by setting its Top property in such way that all 3 can appear one by one in one column. Here though 3 CheckBox - object created it has not altered row height as it is not part of row's cell range. It is like floating on document. There 3 checkbox can float over even below row without changing row height. This is successfully implemented for Checkbox and Option butons.

    I am thankful to you and also accepting your code sample that is absolutely true.  But as it uses range to add object so it is "embeded" what I mean. I want floating approach to exactly satisfy my question for ComboBox just like I have explained for CheckBox. It is able to create ComboBox using Shapes and AddOLEObject method and also does not increase row height as it is "Floating" what I mean. Only problem is Populating value in to combobox.

    I have last option - Use Check Box and Option Button with Shapes method and for ComboBox use InLineShapes. But I want to maintain uniform style so using two approches I want to avoid.

    Thanks,

     

    Wednesday, June 21, 2006 11:17 AM
  • Ok. Please review following VBA code. I want its VSTO C# conversion. ( Paste following code line into Word 2003 VBA and run it. It will create one ComboBox and populate it with US, UK, AUS. Default Selected value will become UK )

    Private Sub AddCheckBox()
        Set myCB = _
           ActiveDocument.Shapes.AddOLEControl _
           (ClassType:="Forms.ComboBox.1")
        With myCB.OLEFormat.Object
            .AddItem "US"
            .AddItem "UK"
            .AddItem "AUS"
            .Value = "UK"
        End With
    End Sub

    Can we convert it to C# VSTO and run it?  It will solve my Question.

    Thanks,

     

    Wednesday, June 21, 2006 11:49 AM
  • Oh I Got it !!

    private void CreateControl()

    {

    object objClass = "Forms.ComboBox.1";

    object objMissing = missing;

    Word.Shape myCB;

    myCB = this.Application.ActiveDocument.Shapes.AddOLEControl(ref objClass, ref objMissing, ref objMissing, ref objMissing, ref objMissing, ref objMissing);

    myCB.OLEFormat.Object.GetType().InvokeMember("AddItem", System.Reflection.BindingFlags.InvokeMethod, null, myCB.OLEFormat.Object, new object[] { "US" });

    myCB.OLEFormat.Object.GetType().InvokeMember("AddItem", System.Reflection.BindingFlags.InvokeMethod, null, myCB.OLEFormat.Object, new object[] { "UK" });

    myCB.OLEFormat.Object.GetType().InvokeMember("AddItem", System.Reflection.BindingFlags.InvokeMethod, null, myCB.OLEFormat.Object, new object[] { "USA" });

    myCB.OLEFormat.Object.GetType().InvokeMember("Value", System.Reflection.BindingFlags.SetProperty, null, myCB.OLEFormat.Object, new object[] { "UK" });

    }

    Well Problem Solved. I was making two mistakes -1)  try to set "List" like in my this question put up VBA code line.  2) For "AddItem" I was using SetProperty instead of InvokeMethod.

    All well that ends well.

    I sincerely thank you for keeping in me in solution loop.

    Wednesday, June 21, 2006 12:49 PM
  • Hi Patel,

    Nice to see your post, I am also working similar kind of work.

    I have one question, You are adding theree varibales to the object so you written the code of adding variables for 3 times.

    Because If we want to add more variables it's not the way to add to the Shape object....right?

    So how to proceed for that.....Please help me on this, and can you please provide me your code relates to this topic, It can be helpful for me.

     

    Thanks in Advance.

    Look forward to see your reply.

     

    Regards

    Ramu G

     

     

    Wednesday, September 20, 2006 6:53 AM
  • Hi Ramu

    I'm afraid using AddItem is the only way to add to the list of an ActiveX control. There's no way to pass an array, or a collection, or anything like that. You could put the list items into an array or collection then use a foreach loop with AddItem.

    Of course, if you're using VSTO (that is the topic of this forum, after all) there are alternatives to ActiveX controls...

    Wednesday, September 20, 2006 7:03 AM
    Moderator
  • Hi Cindy,

     

    Thanks for your Comments.

    Actually my scenario like this, In a word table, whenever a user selects a single cell, this "Shape object" is floats over that cell with some variables. I am done upto this,

    1. Problem where I am getting is, after ShapeObject is floats over the cell, cursor focus is changes to page start position, but in my case focus can't change, that should be in the selected cell only.

    2. And I want to add some key events also, If user clicks Esc or Enter key, that "shape object" has to be disabled

    Can you please suggest me for how to acheive these issues.

     

    Look forward to see your reply.

     

    Regards

    Ramu G

     

    Wednesday, September 20, 2006 1:12 PM
  • Hi Ramu

    Your situation is still not clear. However, it is clear that 1. your question has nothing to do with VSTO technolgy and 2. it also doesn't apply to an ActiveX combobox (at least, not that I can tell).

    Please post your question in a more appropriate place

    http://msdn.microsoft.com/newsgroups/default.aspx?dg=microsoft.public.office.developer.automation&lang=en&cr=US

    Please specify the programming language you're using, and the version of Word you're targeting. Please include a very detailed description of what you're trying to accomplish and copy in the relevant code you already have. I'm particularly concerned about what you collectively call "shape objects". In Word, these can be many, many different things. I want to understand exactly what you're working with and WHY they're "over" (rather than in - as InlineShapes) table cells.

    As to point (2): there is no way to capture keyboard events with Word. In order to link code to keyboard presses, you MUST have code in a VBA project loaded in the Word application.

    Wednesday, September 20, 2006 1:35 PM
    Moderator
  • Hi Cindy,

    Thanks for your quick reply.

    Technologies I am using:  VSTO 2005, C#.NET, XML, ActiveX (OCX) control and Office2003

    VSTO(word) Presentation
    C#  BusinessLogic
    DAL  XML

    Here my task relates to "Floaties" concept(the name which should be similar to Office2007 concept),

    but here we are developing with managed code(VSTO).

    We are developing some "Workpapers"(which are similar to word documents)  but these Workpapers are

    inter related with XML documents. In XML so many styles, rules are defined, which can be used in

    Workpapers and also it stores values/information of Workpapers. So everytime we are calling the XML

    functions for getting and updating the values.


    Work is in 2 stages,are BuildMode and UseMode. In buildmode, builder can assign a celltype in a table as

    radio/checkbox/dropdown/text filed, once it can be done, In usemode user can't able to change the

    celltype, he can change the value of the Cell.  (so In workpapers all cells must be of

    radio/checkbox/dropdown/text field form)


    In VB, We are creating a single control with three modes, Control is created as OCX, it's having some

    API's (Get Items/variables, selected items/values from C# and update them into C#...)

    So OCX and Shape Objects are interrelated each other.
    because while calling these OCX functionalites we are using Shpe/InlineShape object


    For Ex: I have a table of 3X2 (3 columns and 2 rows) in Workpaper.

    Builder applied 1st row 2nd column cell as RadioFieldCell
            1st row 3rd column cell as CheckboxFieldCell
            2nd row 2nd column cell as DropdoenFieldCell
            2nd row 2nd column cell as TextFieldCell

    So here two more actions are taken palce are "ShowFlaotie" and "HideFloaite"
    If user clicks on a "1st row 2nd column cell", a "RadioField Floatie" is floats over that cell with some

    variables(let's say 4 variables, are "Item1", "Item2", "Item3" and "Item4).

    and after, If user clicks on any other cell, that relavant Floaite has get populate and floats over that

    cell and previous cell Floatie has to be hide.

    There are some rules while populating the Flaotie:
    Floatie, floats over the selected cell only
    Row height can't change......like blahblahblah....


    My previous mail, I mentioned the question at this point.
    While Floaite is populates over the Cell, the focus can't change from that cell
    If user clicks some keys like Esc or Enter it takes the some action then Floaite has to Hide.

     

    I think, I am not cleared you fully because my english writing is some how making difficult for you.
    Please provide me some suggestions and comments.


    Look forward to see you reply.

     

    Regards
    Ramu G

    Wednesday, September 20, 2006 2:51 PM