I've made some changes to Options menu processing to implement the following features. Nice how some small changes amplifies developer abilities. I guess that's due to a well programmed framework and MEF.

  1. Allow developer to specify custom OptionsDialog class.
  2. Clean up of custom OptionsDialogView feature.
  3. Correct issue occurring with second invocation of OptionsDialogView.ShowDialog.

Changes to ToolMenu.cs

        // patch - begin
    [Import(CompositionPoints.Options.OptionsDialog, typeof(IOptionsDialog))]
    private IOptionsDialog optionsDialog { get; set; }

    [Import(ExtensionPoints.Options.OptionsDialog.View, typeof(Lazy<IWindowFactory>), AllowDefault=true, AllowRecomposition = true)]
    private Lazy<IWindowFactory> optionsDialogViewWF { get; set; }

    protected override void Run()
        if (optionsDialog == null)
            optionsDialog = new OptionsDialog();
        optionsDialog.ShowDialog(optionsDialogViewWF == null ? new OptionsDialogView() : optionsDialogViewWF.Value.CreateWindow());

// patch - should be moved to a more appropriate location
public interface IOptionsDialog
    void ShowDialog(Window optionsDialogView);

// patch - should be moved to a more appropriate location
public interface IWindowFactory
    Window CreateWindow();
// patch - end

Changes to OptionsDialog.cs

// patch - removed [Export(CompositionPoints.Options.OptionsDialog, 
class OptionsDialog : AbstractOptionsItem, 
    IOptionsDialog, IPartImportsSatisfiedNotification // patch - insert IOptionsDialog

asked 11 Sep '10, 10:16

BSalita's gravatar image

accept rate: 22%

edited 24 Nov '10, 06:13

Scott%20Whitlock's gravatar image

Scott Whitlock ♦♦

I bow to your superior MEF-ness. :) Using the optional import is much cleaner. I am ashamed to admit I didn't even know about the AllowDefault=true parameter. Heh.

(11 Sep '10, 14:35) Scott Whitlock ♦♦

My instincts told me the feature should be there -- and there it was.

(11 Sep '10, 15:44) BSalita

Do we really need IWindowFactory, or will Lazy< Window > still work? And the first import requires AllowDefault=true as well, right?

(11 Sep '10, 16:23) Scott Whitlock ♦♦

Yes, IWindowFactory is needed. AFAIK, Window.ShowDialog closes the Window rendering the singleton MEF unusable for future use. A second Option Menu call on the same Window MEF object will fail because it was closed by the first ShowDialog. Instead, a factory must be called to make an instance of Window each time. Therefore, IWindowFactory is required.

(11 Sep '10, 16:53) BSalita

Yes, I agree I should have put AllowDefault=true in the first Import because I removed the Export of SoapBox's OptionDialog. Therefore, SoapBox will no longer Export OptionDialog. The only possible Export will be the developer's custom OptionDialog, if present. AllowDefault=true is needed because the exporting is optional.

(11 Sep '10, 16:53) BSalita

Got it. I'll be releasing a new version today (Version 2010.09.11). It will include all outstanding feature requests, including this. I'll post my code below for a review.

(11 Sep '10, 17:06) Scott Whitlock ♦♦
showing 5 of 6 show 1 more comments

Here's what the new ToolsMenuOptions class looks like:

/// <summary>
/// Adds the Options Dialog to the tools menu
/// </summary>
[Export(ExtensionPoints.Workbench.MainMenu.ToolsMenu, typeof(IMenuItem))]
class ToolsMenuOptions : AbstractMenuItem 
    public ToolsMenuOptions()
        ID = Extensions.Workbench.MainMenu.ToolsMenu.Options;
        Header = Resources.Strings.Workbench_MainMenu_Tools_Options;

    [Import(CompositionPoints.Options.DefaultOptionsDialog, typeof(IOptionsDialog))]
    private IOptionsDialog defaultOptionsDialog { get; set; }

    [Import(ExtensionPoints.Options.OptionsDialog_, typeof(IOptionsDialog),
        AllowDefault = true)]
    private IOptionsDialog optionsDialog { get; set; }

    [Import(ExtensionPoints.Options.OptionsDialog.View, typeof(IFactory<Window>), 
        AllowRecomposition=true, AllowDefault=true)]
    private IFactory<Window> optionsDialogView { get; set; }

    protected override void Run()
        var optionsDialogToUse = optionsDialog ?? defaultOptionsDialog;
        optionsDialogToUse.ShowDialog(optionsDialogView != null ? 
            optionsDialogView.Manufacture() : new OptionsDialogView());

Notice I generalized the WindowFactory into an IFactory<t>:

public interface IFactory<T>
    T Manufacture();

I've just got to find a good place for it.


answered 11 Sep '10, 17:12

Scott%20Whitlock's gravatar image

Scott Whitlock ♦♦
accept rate: 50%

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here



Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "Title")
  • image?![alt text](/path/img.jpg "Title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported



Asked: 11 Sep '10, 10:16

Seen: 2,302 times

Last updated: 24 Nov '10, 06:13

powered by OSQA