Problem binding to Imported Property

Sep 6, 2010 at 8:53 AM

So i have set up a system using MEF to import a WPF MenuItem control. I found a way to get it working but i had an issue binding to the Property Directly. The property looks like 

        [ImportMany(AllowRecomposition=true)]
        public ObservableCollection<Lazy<MenuItemPart,IPluginMetadata>> MenuItemExtensions { get; set; }

If i attempt to set the Item Source of the Extensions Menu Item using this code the menu items fail to load with this error "Value is not created" displaying in the menu

        public void OnImportsSatisfied()
        {
            this.ExtensionsMenuItem.ItemsSource = MenuItemExtensions;
        }

But if i manually add them using this code everything works as intended.

 public void OnImportsSatisfied()
        {
            //this.ExtensionsMenuItem.ItemsSource = MenuItemExtensions;

            //load extensions menu items
            if (MenuItemExtensions != null)
            {
                ExtensionsMenuItem.Items.Clear();
                foreach (var menuItem in MenuItemExtensions)
                {
                    this.ExtensionsMenuItem.Items.Add(menuItem.Value);
                }
            }
        }
Is there something i did wrong with the first way? There is no value to be able to bind to.

Sep 7, 2010 at 6:00 PM

That's an ObservableCollection, an enumerable source of type Lazy<MenuItemPart,IPluginMetadata> not sure how well that's gonna go over with the way WPF then iterates through the collection.

Lazy is a very delicate type and using it this way is a bit strange.

This LINQ stuff came to mind, but it's virtually the same thing.

ExtensionsMenuItem.ItemsSource = from x in MenuItemExtensions select x.Value;

I'm gonna settle on just telling on you. This is wrong, the Lazy part is not meant to be exposed like that. It's meant to be able to query metadata and then fetch the right instance (defer the instantiation of parts you don't need).

Sep 7, 2010 at 11:48 PM

I just based this off a lab i did at tech ed. is there another way that you can access the meta data without the lazy loading?

Sep 8, 2010 at 6:24 PM
Edited Sep 8, 2010 at 6:25 PM

No one or no thing is infallible.

You can always browse the catalogs for parts, but it's not very fun. I must ask why you go about it this way? What is it that you trying to do here, because I don't see an actual problem with any of the two, so far working solutions/workarounds that you have.

Sep 8, 2010 at 10:51 PM
I'm making a plugin type model so a third party just needs to inherit the menu item class which is a wpf menu item control and then at start up I load all the extensions into a menu called extensions The main reason I did it this way is because I am new to mef and don't know any other ways
Sep 11, 2010 at 2:18 PM

If you don't need the metadata you can just as easily import the menu items directly, like so:

        [ImportMany]
        public ObservableCollection<MenuItemPart> MenuItemExtensions { get; set; }

Sep 12, 2010 at 7:15 AM

i don't at the moment but i thought it would be a good practice to include it. Also at the moment the MenuItemPart is just a class that inherits from a WPF Control. This forces the person creating the plugin to design it as a wpf control but i was wondering if that is not generally a good practice. I was considering creating an interface with just the information needed and having my app create the MenuItem Control. Doing this though would also give the third party developer a little less control if i didn't support some of the properties. 

Any thoughts, Pro's and Con's that you can think of about doing it either way?

Sep 12, 2010 at 1:28 PM

That depends entirely what you are trying to achieve

a) If you need a testable or abstraction layer for these extensions using interfaces or patterns such as MVVM definitely makes that easier

b) If you want a straight forward composable UI just go with importing stuff. However, having a region management to help with the composability of your UI is generally necessary. This can be very simple but still, you need some orchestration for this to work well.

Which ever is important to you make compromises and design with either one in mind.

Sep 12, 2010 at 1:50 PM

Thanks for your insight