This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
I have a simple Editor with a ComboBox. If I set the ItemsSource of the ComboBox using data binding, it seems that the combobox is populated right away, whether I need it or not. Since filling it is slow, I'd like to defer it (or avoid it) until combo box drops down. The only way I've found to do that is to derive my own ComboBox (MyComboBox for example) and set its ItemSource directly (no data binding) in an event handler. But without data binding there is no context -- MyComboBox has no idea who it is or what is being edited in its event handler. Is there another pattern here? I feel like there is a better WPF way to do this than trapping the DropDown event in MyComboBox. Thanks in advance, |
|
|
Would using an asynchronous binding do the job? See the Binding.IsAsync property (and optionally the PriorityBinding class). The potential difficulty here is that if filling is *really* slow the user could drop down the combo box before the binding has completed; one possible way around that is to priority-bind the ComboBox.IsEnabled property so that it remains disabled (and hopefully displaying a suitable message!) while it is filling. And of course you incur the cost of filling the combo box even if the user never uses it -- probably no big deal in terms of local resources unless the list of items is *really* big, but if the binding is hitting a shared resource such as a database, then it could increase the load on that shared resource. Otherwise this is probably the most "WPFish" solution. If you prefer to stick with synchronous filling in the DropDown event handler, there are a couple of ways for the handler code to get at the information it needs to fill the drop-down, depending on your requirement: 1. Data bind the Tag property, or a custom attached property, on the combo box, and access it using the sender parameter of the event handler. The thread at http://www.mindscape.co.nz/forums/Thread.aspx?PostID=1749 describes how to do this (in a different context). This strategy is appropriate if your DropDown handler needs access to the item being edited (value, source object or property metadata: see ObjectWrapper). 2. If your DropDown handler needs additional information that may vary between instances, but is *not* part of the edited object data or metadata, you can provide this using PropertyEditor.EditContext. This allows you to specify a value on the editor declaration and access it from the editor template. Again, data bind Tag or a custom attached property to EditContext, and access it from the event handler just as in option 1. EditContext is a bit obscure and elusive so let me give you a (rather silly) example so you can determine whether it meets your needs. Suppose you have a bunch of properties that you want to edit using a delay-filled combo box that gets the permitted values from a database. But each property has a different set of possible values -- e.g. Manufacturer, Model, Colour. You don't want to create multiple DataTemplates just so you can query different tables for the list of values; nor do you want the DropDown handler to have to know how to query for specific properties. You want to create one DataTemplate with the delay-fill logic, and pass it the information it needs to populate each property. You can do this by providing the query information inthe EditContext. Thus: <DataTemplate x:Key="DelayFillComboBox"> <PropertyEditor PropertyName="Manufacturer" EditorTemplate="{StaticResource DelayFillComboBox}"> Obviously in real life you wouldn't put SQL into your UI layer -- I did say this was a rather silly example! But hopefully it gives you some idea of what EditContext is for. Note: EditContext is available only in nightly builds so if this sounds like what you need then make sure you are using a recent nightly. |
|
|
Thanks, the Binding.IsAsync method seems to work very well in this case. -Paul |
|