Thursday, August 30, 2012

Interacting with a sub-processed shell in .Net

A while ago I asked on StackOverflow for some help with System.Diagnostics.Process. I was unable to make it work correctly to interact with the Flex Compiler Shell (fcsh.exe).

I accepted my own answer where I just gave up on the managed Process class and dealt directly with the Windows API.

Recently someone commented on my answer saying it doesn't work for him or her. I couldn't really help the commentator as my code had evolved a lot since I posted that answer. So I decided to blog about the code I now use.

In my latest code, I created an abstract class, ShellProcess, which should, in theory, allow interacting with any shell. ShellProcess is then sub-classed as FcshProcess. Both classes are shown below.

In this example, I obtain the output of the help command:

In debug, the output is:

List of fcsh commands:
mxmlc arg1 arg2 ... full compilation and optimization; return a target id
compc arg1 arg2 ... full SWC compilation
compile id incremental compilation
clear [id] clear target(s)
info [id] display compile target info
quit quit
(fcsh)

Note that ShellProcess.cs also holds a static class named Kernel32 that contains the API methods, structs and consts. I keep these separate in my project.

Sunday, July 29, 2012

A WPF Watermarked TextBox

A watermarked text box is a very natural thing nowadays, but I have had a hard time finding one that works in all circumstances with WPF. Some issues I have had with already made solutions from the Internet are:
  1. The watermark will end up as the value of the target property of a data-bound text box.
  2. Watermark appears behind or above the text of an already populated data-bound text-box
  3. Watermark doesn't disappear when the TextBox is the control that gets the initial focus.
Recently however I stumbled upon a solution that uses behaviors. While I had to tweak it for some of the issues mentioned above, I now finally have watermarked TextBoxes that seem work correctly.

I'd like to give credit to the author of the following blog post for providing me with the basis of my working solution:


Here is the Behavior:
And here is an example with a style for the watermark: If you find any issues with the above please let me know as I am interested to make sure this watermark behavior works properly at all times.

Sunday, June 10, 2012

Provide EntityObjects access to their ObjectContext

I'm busy learning Entity Framework which I've been finding quite amazing, especially because it seems to work just fine with system.data.sqlite.

I implemented an undo/redo mechanism in an  MVVM/WPF application I'm converting to EF. To stick to the MVVM design pattern, I need that EntityObjects themselves add undo points. I wasn't sure how to get this done as EntityObjects don't reference their ObjectContext.

So I figured that I would need to choose between two approaches:
  1. Make the ObjectContext global.
  2. Add a property to EntityObjects partial classes that hold the reference to the ObjectContext.
Since my application is already using MEF, using the first approach could've been implemented by letting EntityObjects access their ObjectContext like this:

But I see a couple of issues with that:
  • What if I have more than one database session each with their distinct ObjectContext?
  • ObjectContext isn't really a service, unlike say, a dialog service.
So I ended up with the second approach. There are already solutions out there, and the one I chose was satisfying with some tweaking. The main issue with the posted solution is that it does dynamic binding which causes a binding exception for any EntityObject that doesn't have the required property. I believe exceptions should be exceptional, so I changed the code to use an interface that specifies the ObjectContext property:

And this is the implementation of the OnContextCreated partial method:

As a last step, I implement IHasObjectContext on EntityObjects as needed.

Sunday, April 29, 2012

In-memory MP3 Encoding With C#

I couldn't find a good enough .Net library to encode MP3s. I settled with interacting directly with libmp3lame.dll. This has the advantage of doing everything in memory.

libmp3lame.dll is an API that wraps LAME's core API. It however remains a bit involved to use, so I wrote a wrapper class.

You can either compile libmp3lame.dll yourself from the latest sources, or grab a build from the web.

Here is the C# class that interacts with libmp3lame.dll:

Tuesday, April 24, 2012

RelayCommand and Dynamic Command Sources (part 2/2)

In my previous post, I described the issue with using RelayCommand with dynamic command sources. In this post, I describe the solution I use.

As I mentioned in my previous post, the issue is that the command source (e.g. a button) does not unsubscribe from CanExecuteChanged of the command it is bound to, so that whenever CommandManager.RequerySuggested fires, CanExecute fires as well, long after the command source is gone.

To solve this I implemented IDisposable on RelayCommand, and added the necessary code so that whenever a model object is removed, and so is removed from the UI, Dispose() is invoked on all its RelayCommand.

This is the modified RelayCommand:
public class RelayCommand : ICommandIDisposable
{
    #region Fields
 
    List<EventHandler> _canExecuteSubscribers = new List<EventHandler>();
    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;
 
    #endregion // Fields
 
    #region Constructors
 
    public RelayCommand(Action<object> execute)
        : this(execute, null)
    {
    }
 
    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");
 
        _execute = execute;
        _canExecute = canExecute;
    }
 
    #endregion // Constructors
 
    #region ICommand
 
    [DebuggerStepThrough]
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }
 
    public event EventHandler CanExecuteChanged
    {
        add
        {
            CommandManager.RequerySuggested += value;
            _canExecuteSubscribers.Add(value);
        }
        remove
        {
            CommandManager.RequerySuggested -= value;
            _canExecuteSubscribers.Remove(value);
        }
    }
 
    public void Execute(object parameter)
    {
        _execute(parameter);
    }
 
    #endregion // ICommand
 
    #region IDisposable
 
    public void Dispose()
    {
        _canExecuteSubscribers.ForEach(h => CanExecuteChanged -= h);
        _canExecuteSubscribers.Clear();
    }
 
    #endregion // IDisposable
}
Wherever I use the above, I use the following pattern where instantiated RelayCommands are tracked and disposed when the time comes:
Dictionary<stringRelayCommand> _relayCommands = new Dictionary<stringRelayCommand>();

public ICommand SomeCmd
{
    get
    {
        RelayCommand command;
        string commandName = "SomeCmd";
        if (_relayCommands.TryGetValue(commandName, out command))
            return command;
        command = new RelayCommand(
            param => { },
            param => true);
        return _relayCommands[commandName] = command;
    }
}

void Dispose()
{
    foreach (string commandName in _relayCommands.Keys)
        _relayCommands[commandName].Dispose();
    _relayCommands.Clear();
}