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, 
    typeof(IOptionsDialog))]
class OptionsDialog : AbstractOptionsItem, 
    IOptionsDialog, IPartImportsSatisfiedNotification // patch - insert IOptionsDialog

asked 11 Sep '10, 10:16

BSalita's gravatar image

BSalita
276131417
accept rate: 22%

edited 24 Nov '10, 06:13

Scott%20Whitlock's gravatar image

Scott Whitlock ♦♦
696262833

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 ♦♦
1

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;
        SetIconFromBitmap(Resources.Images.Workbench_MainMenu_ToolsMenu_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.

link

answered 11 Sep '10, 17:12

Scott%20Whitlock's gravatar image

Scott Whitlock ♦♦
696262833
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

By RSS:

Answers

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

Tags:

×17
×11
×7
×6
×4
×1
×1

Asked: 11 Sep '10, 10:16

Seen: 2,176 times

Last updated: 24 Nov '10, 06:13

powered by OSQA