This project is read-only.
Quick Start - for users of MVVM Light Toolkit
The easiest way to use WorkingFileManager is if you happen to use the MVVM pattern in your application, particularly with the MVVM Light Toolkit (WorkingFileManager can take advantage of the messaging framework provided by this toolkit).

The sample application included with the source demonstrates a simple working text editor that has New, Open, Save, Save As, Exit, and Recent Files features. This application takes the simplest approach to incorporating WorkingFileManager, which is to leverage the MVVM Light Toolkit and to use the default provided commands for handling menu interaction. This tutorial will describe the important characteristics of the sample.

Add WorkingFileManager.dll and WorkingFileManager.MVVM.dll to your ViewModel and View projects.
These files contain the basic WorkingfileManager objects and the additional code to easily integrate with MVVM Light.

Implement the IWorkingFileOwner interface.
The class that implements this interface can be your MainWindowViewModel. This interface contains important methods related to saving your data and to displaying things in the view. Full documentation can be found in the source, but generally:

CoreSaveFile(string) - is a method that saves the current working data to a file. WorkingFileManager does not provide an implementation because this will depend on your data. For example, the sample project is a basic text editor and therefore saves the contents of a text editor straightforwardly into a text file. This method MUST report (via the ReportPerformedFileEvent) to the WorkingFileState object when a file has been successfully saved.

CoreOpenFile(string) - is a method that populates your application with data that has been loaded from a file. Again this implementation depends on what exactly your application does. This method MUST report (via the ReportPerformedFileEvent) to the WorkingFileState object when a file has been successfully opened. It should also report when a file fails to open (due to a permissions exception etc) via a call to ReportPerformedFileEvent.

CoreNewFile() - populates your application with new blank working data. This MUST report (via the ReportPerformedFileEvent) to the WorkingFileState object when new data has been successfully been loaded.

GetWorkingFileState() - should return the WorkingFileState object that your application uses to track state.

GetInitialDirectory(FileActionTypes) - this is used to specify the starting directory for OpenFileDialogs and SaveDialogs that are launched in response to various menu commands.

GetInitialFilter(FileActionTypes) - this is used to specify the file filter for OpenFileDialogs and SaveDialogs that are launched in response to various menu commands.

GetWindowText(FileActionTypes) - specifies the message contained in popup windows that appear in response to various menu commands, for example, the text that is displayed when you try to exit your application without saving.

GetWindowTitle(FileActionTypes) - specifies the title text of popup windows that appear in response to various menu commands, for example, the title of the popup that is displayed when you try to exit your application without saving.

Create a WorkingFileState object as a non-static, non-property member in your MainWindowViewModel.
We will be reporting to this object when certain things happen like a file is successfully opened. IWorkingFileOwner.GetWorkingFileState() should return this object. Your code will probably never need this method, but it allows other parts of the WorkingFileManager to find a reference to the WorkingFileState object when it needs it.

private WorkingFileState _workingFileState = new WorkingFileState();

public WorkingFileState GetWorkingFileState()
{
   return _workingFileState;
}
Create a public DefaultFileCommandImplementations property on your MainWindowViewModel.
This object contains all the Commands that we will bind our menu XAML to. When it is instantiated, it must be passed a reference to the IWorkingFileOwner you implemented (i.e. this if you implemented the interface in your MainWindowViewModel).
public DefaultFileCommandImplementations DefaultFileCommandImplementations { get; private set; }

//...in MainWindowViewModel constructor
DefaultFileCommandImplementations = new DefaultFileCommandImplementations(this);
Report to the WorkingFileState object when your data becomes dirty.
For example, in the sample application, when the text that is displayed in the text editor changes, we inform the WorkingFileState.
public string Text
{
   get
   {
      return _Text;
   }
   set
   {
      if (_Text != value)
      {
         _Text = value;
         _workingFileState.ReportPerformedFileEvent(WorkingFileState.PerformedFileEvents.Dirtied, null);
         NotifyPropertyChanged("Text");
      }
   }
}
private string _Text;
In your MainWindow.xaml file (or where ever you want to add the menu), add a namespace for WorkingFileManager.MVVM.
xmlns:WFMVM="clr-namespace:WorkingFileManager.MVVM;assembly=WorkingFileManager.MVVM"
In the same XAML, add some code to allow us to bind MenuItems from MenuItemViewModel objects.
<Window.Resources>
   <Style TargetType="{x:Type MenuItem}">
      <Setter Property="Header" Value="{Binding Path=Header}"/>
      <Setter Property="Command" Value="{Binding Path=Command}"/>
      <Setter Property="CommandParameter" Value="{Binding Path=CommandParameter}"/>
   </Style>
   <HierarchicalDataTemplate DataType="{x:Type WFMVM:MenuItemViewModel}"
      ItemsSource="{Binding Path=MenuItems}">
   </HierarchicalDataTemplate>
</Window.Resources>
Add your menu XAML.
Presumably we are editing MainWindow.xaml and this uses MainWindowViewModel (where you created the DefaultFileCommandImplementations property) as its viewmodel.
<Menu IsMainMenu="True">
      <MenuItem Header="File">
      <MenuItem Header="New" Command="{Binding DefaultFileCommandImplementations.CmdNew}" />
      <MenuItem Header="Open..." Command="{Binding DefaultFileCommandImplementations.CmdOpen}" />
      <MenuItem Header="Save" Command="{Binding DefaultFileCommandImplementations.CmdSave}" />
      <MenuItem Header="Save As..." Command="{Binding DefaultFileCommandImplementations.CmdSaveAs}" />
      <MenuItem Header="Recent" ItemsSource="{Binding DefaultFileCommandImplementations.RecentFileMenuItemViewModels}" />
      <MenuItem Header="Exit" Command="{Binding DefaultFileCommandImplementations.CmdExit}" />
   </MenuItem>
</Menu>
Add code to your view to handle messages that will be send from the DefaultFileCommandImplementations object.
In your MainWindow.xaml.cs (codebehind), add the following to the constructor:
Messenger.Default.Register<NewFileMessage>(
    this,
    msg =>
    {
        WorkingFileManager.ViewMethods.HandleNewFileMessage(msg.nfmparams, this);
    }
);

Messenger.Default.Register<OpenFileMessage>(
    this,
    msg =>
    {
        WorkingFileManager.ViewMethods.HandleOpenFileMessage(msg.ofdparams, this);
    }
);

Messenger.Default.Register<OpenRecentFileMessage>(
    this,
    msg =>
    {
        WorkingFileManager.ViewMethods.HandleOpenRecentFileMessage(msg.orfparams, this);
    }
);

Messenger.Default.Register<SaveAsFileMessage>(
    this,
    msg =>
    {
        WorkingFileManager.ViewMethods.HandleSaveFileMessage(msg.sfdParams, this);
    }
);

Messenger.Default.Register<ExitMessage>(
    this,
    msg =>
    {
        WorkingFileManager.ViewMethods.HandleExitMessage(msg.exitParams, this);
    }
);
Now you have the basic code in place to display a menu and handle its events.

Call the CmdExit command in your Window_Closing event
void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    var viewModel = this.DataContext as MainWindowViewModel;
    viewModel.DefaultFileCommandImplementations.CmdExit.Execute(null);
    e.Cancel = true;
}
This will allow the WorkingFileManager to respond to attempts to shutdown the program through the close button. It is important to cancel the event. The CmdExit command itself will instruct the application to shut down when appropriate.

Additional Customizations
Once your menu is set up, you can make additional customizations in the View. For example, to add a set of shortcuts, you can add the following to the window that contains the menu:
<Window.InputBindings>
   <KeyBinding Key="N" Modifiers="Ctrl" Command="{Binding DefaultFileCommandImplementations.CmdNew}" />
   <KeyBinding Key="O" Modifiers="Alt" Command="{Binding DefaultFileCommandImplementations.CmdOpen}" />
   <KeyBinding Key="S" Modifiers="Ctrl" Command="{Binding DefaultFileCommandImplementations.CmdSave}" />
   <KeyBinding Key="F4" Modifiers="Alt" Command="{Binding DefaultFileCommandImplementations.CmdExit}" />
</Window.InputBindings>

You can add images to your menu as you would with any standard XAML menu. For example, instead of
<MenuItem Header="Open ..." Command="{Binding DefaultFileCommandImplementations.CmdOpen}" />
You could specify an image with
<MenuItem Header="Open ..." Command="{Binding DefaultFileCommandImplementations.CmdOpen}">
   <MenuItem.Icon>
      <Image Source="Images/Menu/open.png" Height="16" Width="16" />
   </MenuItem.Icon>
</MenuItem>

More Information
You can read more about the following topics:
Recent Files

Last edited Oct 5, 2014 at 1:53 AM by jmtonn, version 9

Comments

No comments yet.