![]() |
Click here to advertise with us
|
|
|||||||
![]() |
|
|
LinkBack | Thread Tools | Display Modes |
|
|||
|
Hi,
I have created the following UserControl (simplified to the bare minimum for clarity): <UserControl x:Class="StealthComboBox"> <Grid></UserControl><Label Name="lblHeader" /></Grid> I would like the users of my UserControl to be able to add items to the ComboBox through code. I have tried a few things already by adding code to the StealthComboBox class, here are 2 examples: Public Items as ItemCollection = cboBox.Items Even though the UserControl builds fine, trying to add it to a project gives me the error "Could not create an instance of type:StealthComboBox" Public DropDownList as ComboBox = cboBox The UserControl builds fine and I could add it to my project - it displays fine and Intellisense shows the ComboBox properties fine. However the "DropDownList" item is actually "Nothing": it does not reference to the cboBox inside my UserControl and any attempt to use it gives an NullReferenceException. Is there a simple way to directly expose the ".Items" and ".SelectedItem" properties and methods in a UserControl? I know that I can create home-made functions in my "StealthComboBox" class that will query the ComboBox values or use its .Items.Add function, like this: Public Function Add(obj_ as Object) as Integer Return cboBox.Items.Add(_obj)End Function Public Function SelectedItem() as Object Return cboBox.SelectedItem()End Function This works pretty well, actually. But I'm mostly wondering if there's a more conventional way - one that would give my UserControl the full interface of a ComboBox instead of me "handpicking" the ones I think I will need? And a more advanced question: what if I want a UserControl with 2 ComboBox items that must be exposed to the user? Isn't there a way to create some kind of "UserControl.List1" and "UserControl.List2", where each of them acts on a separate ComboBox list? (i.e. UserControl.List1.Items.Add and UserControl.List2.Items.Add) Thanks for the help! |
|
||||
|
If you don't want to change the functionality mirroring those properties is usually what you do. That means using the same signature and get/set the internal objects property. Take for example Items property, when you look it up in help you get this page (this property is inherited from ItemsControl class) ItemsControl.Items Property (System.Windows.Controls) At top of page you see the declaration:
Code:
<BindableAttribute(True)> _ Public ReadOnly Property Items() As ItemCollection Code:
<BindableAttribute(True)> _
Public ReadOnly Property Items() As ItemCollection
Get
End Get
End Property
Code:
Return CB.Items
__________________
Some useful links: Learning videoes, Code Samples, WMI Code Creator, MSDN, The Code Project, WindowsClient.net, ASP.net, W3 Schools, Regular-Expressions.info, GDI+ FAQ
How to format posts with code blocks etc - present the problem/post properly ![]() |
|
|||
|
Thanks for the quick replies!
However, none of your suggestions will retain the full functionalities of the ComboBox. It does work fine and having the ObjectCollection exposed is better functionality than a single link to the .Add method, and is enough for what I need to do (but so was my original code). Imagine a DataGrid - you will want to keep a LOT of the features it has and you probably don't want to relink everything manually... I thought of something overnight though, and I just tried it and it works perfectly. It also answers my "what if you need 2 ComboBox to retain full functionality" question. Basically, i was very close when I exposed a public variable that would link to my cboBox: Code:
Class StealthComboBox
Public myBox as ComboBox = cboBox
End Class
By changing the variable to a readonly property (this is what i dreamed about last night...): Code:
Class StealthComboBox
Public Readonly Property myBox() As ComboBox
Get
Return cboBox
End Get
End Property
End Class
If I would create a UserControl with, let's say, 2 ComboBox: one with Country and the other one with State, the easiest way to let the code access both of them would be: Code:
(XAML)
<UserControl Name="CountryStateSelector">
<Grid>
<ComboBox Name="_CountrySelector" />
<ComboBox Name="_StateSelector" />
</Grid>
</UserControl>
(Code-Behind)
Class CountryStateSelector
Public Readonly Property CountrySelector() as ComboBox
Get
Return _CountrySelector
End Get
End Property
Public Readonly Property StateSelector() as ComboBox
Get
Return _StateSelector
End Get
End Property
End Class
Code:
(XAML)
<my:CountryStateSelector Name="LocationSelector" />
(Code-Behind)
Public Sub somesub()
LocationSelector.CountrySelector.Items.Add("USA")
LocationSelector.CountrySelector.Items.Add("Canada")
LocationSelector.StateSelector.Items.Add("Boston")
LocationSelector.StateSelector.Items.Add("Quebec")
End Sub
The only drawback of this approach is that the combo box still isn't reachable through XAML so I can't use databinding. But for what I need to do, this is sufficient. I guess I could easily map a bindable property to the objectcollection afterward if i need databinding. yay! |
|
||||
|
That combobox is already exposed in that fashion (Friend access level); you can write LocationSelector.cboBox to access it. This actually something one usually want to avoid to protect the internal objects, and outside assembly it is. More so exposing properties on the UserControl itself allow Designer support, you can for example set the usercontrol Items in Designer with the property I posted. From what I see that is also possible by exposing the control as regular property (not ReadOnly) in WPF, then you get a sublevel in Properties window for all the internal controls properties, IMO this is not desirable. Designer/Design-time support is of great importance and should be a main consideration when developing custom controls for a visual development environment.
__________________
Some useful links: Learning videoes, Code Samples, WMI Code Creator, MSDN, The Code Project, WindowsClient.net, ASP.net, W3 Schools, Regular-Expressions.info, GDI+ FAQ
How to format posts with code blocks etc - present the problem/post properly ![]() |
|
|||
|
Quote:
For the rest, I agree that your approach seems more conventional and probably more useful for designers. However for the sake of these usercontrols, it's not meant to be distributed and I'm the designer - they're mainly just a way for me to quickly place elements that are redundant in my application in an effort to lighten my XAML code that was beginning to be hard to maintain due to a "Tabs" apporoach. Thanks a lot for the help and explanations - I have a better understanding of its mechanics now and the info could definitely be useful on future projects. |
|
||||
|
Quote:
As the developer everything is your choice, but in case you misinterpreted this; "Designer" is visual part in IDE, as in "View Designer"
__________________
Some useful links: Learning videoes, Code Samples, WMI Code Creator, MSDN, The Code Project, WindowsClient.net, ASP.net, W3 Schools, Regular-Expressions.info, GDI+ FAQ
How to format posts with code blocks etc - present the problem/post properly ![]() |
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|