Feeds:
Posts
Comments

Archive for March, 2010

I needed an Exif reader class for a C# application I was working on, and though I found quite a few implementations available including a few on The Code Project, none of them fully suited my requirements. So I wrote my own class. The article describes the use and implementation of this class, and also includes a couple of demo projects, one using Windows Forms and the PropertyGrid, and another using WPF and the growingly popular MVVM architecture. The ExifReader project is 100% Style Cop compliant except for the IDE generated AssemblyInfo.cs and the PropertyTagId.cs file which I custom created from multiple sources including some GDI+ header files, as well as trial and error. I didn’t think it would be a great idea to try and apply Style Cop guidelines to either of those files. The class does not directly access Exif metadata from image files, and instead delegates that functionality to the Image class from System.Drawing. The public interface does not expose any System.Drawing types and so this library can be used from WPF without needing to reference System.Drawing.

Article link

This class tries to cover as many of the documented and undocumented Exif tags as I could test on, but if any of you encounter images that have Exif tags that are not recognized by my class, I request you to kindly contact me and send me the images. Once I have the images, I can attempt to support those tags too. Right now, if it encounters an undocumented tag it will still extract the tag value, but you won’t see any descriptive tag-name or any custom parsing/formatting that may be required.

All the code, including the demos, have been written and tested on VS 2010 RC and .NET 4.0. While I have not intentionally used any .NET 4.0/C# 4.0 only feature like say the dynamic keyword, I may have inadvertently written code that may not compile in .NET 3.5. But I don’t expect any of those to be hard to fix or change for most programmers, but if you run into trouble and can’t figure out what to do, please ping me via the article forum and I’ll help fix it. I suspect the most common compatibility issues would be with regard to IEnumerable<T> cast requirements in .NET 3.5, since it became a variant interface only in .NET 4.0.

Read Full Post »

Recently I was working on an MVVM demo for an article where I wanted live filtering based on the contents of a text box. The problem with this is that the TextBox does not have a Command property, and thus I’d need to use code-behind to proxy its text changed event to the ViewModel. And I did not want to do that. This was purely whimsical behavior on my part since MVVM does not mandate this at all, though a lot of people do recommend it. Apparently, you can get around this by referencing an Expression Blend DLL, which has support for interaction triggers that you can forward to a command object, thereby avoiding any code-behind. I didn’t want to reference an Expression Blend DLL, not for a simple demo app anyway and so I was forced to work around it by adding an attached behavior to the TextBox that could take a command object. This was a bit of an over-kill of course, and in a real world app I’d simply do it in code-behind. Most likely something like :

ViewModel viewModel = this.DataContext as ViewModel;

. . .

private void TextChanged(. . .)
{
    viewModel.SomeCommand(. . .) ;
}

That’d be in my view’s code-behind, and while some purists may not be too happy, I think it’s definitely simpler than referencing Expression Blend! Here’s what a typical Xaml code snippet using this behavior would be like:

<TextBox x:Name="searchTextBox" Width="165"
  HorizontalAlignment="Left" Margin="3,0,0,0"
  Text="{Binding SearchText}"
  local:TextChangedBehavior.TextChanged="{Binding FilterCommand}" />

Instead of handling the TextChanged event, I handle it via the attached behavior and route it to the FilterCommand command object in the ViewModel. Here’s the code for the attached behavior:

internal class TextChangedBehavior
{
    public static DependencyProperty TextChangedCommandProperty
        = DependencyProperty.RegisterAttached(
          "TextChanged",
          typeof(ICommand),
          typeof(TextChangedBehavior),
          new FrameworkPropertyMetadata(
            null,
            new PropertyChangedCallback(
              TextChangedBehavior.TextChangedChanged)));

    public static void SetTextChanged(TextBox target, ICommand value)
    {
        target.SetValue(TextChangedBehavior.TextChangedCommandProperty,
          value);
    }

    public static ICommand GetTextChanged(TextBox target)
    {
        return (ICommand)target.GetValue(TextChangedCommandProperty);
    }

    private static void TextChangedChanged(
      DependencyObject target, DependencyPropertyChangedEventArgs e)
    {
        TextBox element = target as TextBox;

        if (element != null)
        {
            if (e.NewValue != null)
            {
                element.TextChanged += Element_TextChanged;
            }
            else
            {
                element.TextChanged -= Element_TextChanged;
            }
        }
    }

    static void Element_TextChanged(object sender, TextChangedEventArgs e)
    {
        TextBox textBox = (TextBox)sender;
        BindingExpression bindingExpression = textBox.GetBindingExpression(
          TextBox.TextProperty);

        if (bindingExpression != null)
        {
            bindingExpression.UpdateSource();
        }

        ICommand command = GetTextChanged(textBox);

        if (command.CanExecute(null))
        {
            command.Execute(null);
        }
    }
}

Nothing complicated there, just a basic attached behavior implementation.

Read Full Post »

Follow

Get every new post delivered to your Inbox.