BBCode executing command with parameter

Apr 28, 2013 at 11:56 AM
Hi,

I discovered ModernUI a few days ago and I must say it is really amazing, especially compared to what other similar projects have to offer.

Anyway, I have this application where I need to execute a command using a BBCode link with a parameter. So I have read this page which explains the XAML part very well: https://mui.codeplex.com/wikipage?title=Link%20navigation%20with%20BBCodeBlock&referringTitle=Documentation

I understand I am supposed to use this:
<mui:BBCodeBlock BBCode="[url=cmd://mycommand|my%20parameter]execute my command[/url]" />
... But unfortunately I'm still a little new to C# and I don't feel very comfortable with interfaces yet, I really do not know how to implement "mycommand" in my application :(

Can you please help me out with this? I've been struggling all morning to find how to do it..

Thanks in advance!
Coordinator
Apr 28, 2013 at 12:36 PM
Edited Apr 28, 2013 at 12:38 PM
There are two steps required, step 1) implement your command and step 2) register the command with the BBCodeBlock link navigator.

There are various way to implement an ICommand. One option is to implement your command as stand-alone class. Deriving from CommandBase, an abstract base implementation of ICommand, located in the FirstFloor.ModernUI.Presentation namespace.
public class MyCommand : CommandBase
{
  protected override void OnExecute(object parameter)
  {
    // TODO: implement command execution
  }
}
Or more commonly used, implement a command as part of your view model and use RelayCommand to relay command execution by invoking delegates. Both NotifyPropertyChanged and RelayCommand classes are also located in the FirstFloor.ModernUI.Presentation namespace.
public class MyViewModel : NotifyPropertyChanged
{
  public MyViewModel()
  {
    this.MyCommand = new RelayCommand(o => DoSomething(o));
  }

  private void DoSomething(object o)
  {
    // TODO: implement command execution
  }

  public RelayCommand MyCommand {get; private set;}
}
Next you need to register your command with the BBCodeBlock link navigator and provide a uri which identifies the command.

When using a command as stand-alone class, you can instantiate the command in XAML. The x:Key uniquely identifies the command so it can be used in BBCode. The xml prefix local should map to the namespace where your command is located.
<mui:BBCodeBlock>
  <mui:BBCodeBlock.LinkNavigator>
    <mui:DefaultLinkNavigator>
      <mui:DefaultLinkNavigator.Commands>
        <local:MyCommand x:Key="cmd://mycommand" />
      </mui:DefaultLinkNavigator.Commands
    </mui:DefaultLinkNavigator>
  </mui:BBCodeBlock.LinkNavigator>
</mui:BBCodeBlock
When your command is part of a view model, you'll need to register your command in code. The following view model defines a link navigator property and registers the command.
public class MyViewModel : NotifyPropertyChanged
{
  public MyViewModel()
  {
    this.MyCommand = new RelayCommand(o => DoSomething(o));
    this.LinkNavigator = new DefaultLinkNavigator();
    this.LinkNavigator.Commands.Add(
      new Uri("cmd://mycommand", UriKind.Absolute), this.MyCommand);
  }

  private void DoSomething(object o)
  {
    // TODO: implement command execution
  }

  public RelayCommand MyCommand {get; private set;}
  public ILinkNavigator LinkNavigator {get; private set;}
}
Then in XAML your bind the link navigator to the BBCodeBlock (assuming the viewmodel is set as datacontext):
<mui:BBCodeBlock LinkNavigator="{Binding LinkNavigator}" />
Two final remarks:
Your command is now registered to a single BBCodeBlock instance. You may want to re-use the link navigator not just for one, but for all BBCodeBlocks in your app. For that you need to define an implicit BBCodeBlock style in App.xaml. See also the Navigation.xaml page in the source code of the mui demo app,

And second; command implementation and registration is even easier when you use MEF. See this document page for more details on using MEF, the included source code provide an exportable command link navigator.
Apr 28, 2013 at 5:01 PM
Thank you ! This really helped me out a lot :)