INotifyPropertyChanged diagnostics

by Brian Keating Thu, May 13 2010 21:41

Those of you that use INotifyPropertyChanged may have noticed it's easy to break the code if you choose to refactor/rename as the property name string does not get refactored.

Here is a mechanism to catch this problem at the implementation stage.

 

#region Debugging Aides

/// <summary>
/// Warns the developer if this object does not have
/// a public property with the specified name. This
/// method does not exist in a Release build.
/// </summary>
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
    // Verify that the property name matches a real, 
    // public, instance property on this object.
    if (TypeDescriptor.GetProperties(this)[propertyName] == null)
    {
        string msg = "Invalid property name: " + propertyName;

        if (this.ThrowOnInvalidPropertyName)
            throw new Exception(msg);
        else
            Debug.Fail(msg);
    }
}

/// <summary>
/// Returns whether an exception is thrown, or if a Debug.Fail() is used
/// when an invalid property name is passed to the VerifyPropertyName method.
/// The default value is false, but subclasses used by unit tests might
/// override this property's getter to return true.
/// </summary>
protected virtual bool ThrowOnInvalidPropertyName { get; private set; }

#endregion // Debugging Aides

#region INotifyPropertyChanged Members

/// <summary>
/// Raised when a property on this object has a new value.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged = (s, e) => { };

/// <summary>
/// Raises this object's PropertyChanged event.
/// </summary>
/// <param name="propertyName">The property that has a new value.</param>
protected virtual void OnPropertyChanged(string propertyName)
{
    this.VerifyPropertyName(propertyName);
    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));           
}

#endregion // INotifyPropertyChanged Members

Tags:

C#

C# on the iPhone

by Brian Keating Wed, February 24 2010 23:08

Recently I've noticed that the country has gone iPhone mad and I'm starting to buy into it myself... my blackberry days may be numbered as the only distinct advantage I see is that bandwidth is not used retrieving emails... but nowadays bandwidth is not so much as issue,, e.g. you get 2gb a month on a vodafone contract Cool

I've had a bit of a play around with Objective-C, interesting but .NET is my forte so I was delighted to see that it was possible (kinda0 to write code in c# for the iPhone platform.

The success of .NET platform from MS on multiple systems came when the Mono project became real. This open-source framework (cross-platform) brought the speed of C# development to Linux and OSX platforms. And now it will take us further.

As we all know, Apple has a highly strict inclusion policy for third-party runtime environments, which makes impossible to distribute apps that use this technology, like .NET and Java. So how can I be talking about .NET on the iPhone?

Because of a process called Static Compilation. Mono had already created a way to generate native code from common intermediate language (CIL) produced by .NET in native code in the past (AOT Ahead-OfTime compilation), with the intention of helping to reduce the speed of the initialization process and increase the process sharing among multiple processes. However, to keep the portability among different machines, a small piece of code was still in JIT (just-in-time) compilation – this method is the key to virtual machine systems that generate intermediate code which is converted to native code during execution.

So this process generates the final result in native code BEFORE the executing time, and this decreases also the size of the final app (since framework must go with the app), which does not need to load the codes to execute JIT and interpret CIL – even though it still adds approximately 6Mb from mono framework itself in the app’s final size.

There are also a few other tricks and Mono features that developers can use to reduce the size of Mono executables and assemblies for deployment in mobile environments. You can use the Mono linker to shrink the library size, you can omit the JIT and code generation engines from the executables, and you can strip out CIL instructions from the assemblies.

Static compilation makes it possible to build Apple-approved iPhone applications with Mono, but it comes with some limitations. Generics and dynamically-generated code are currently not supported when AOT compilation is used.

There are a lot of hoops to jump through right now to set up iPhone cross-compilation for Mono, but de Icaza (Novell's lead mono developer) says that developers who want to start now can use Unity, a third-party commercial programming framework for 3D game development that is built on Mono. Unity supports several platforms, including the iPhone and the Wii, and comes with its own built-in Mono cross-compilation environment.

Nowadays, thank to Unity 3D, there are over 40 apps (mostly games) on App Store that were written in C# and that carry mono framework inside. Wouldn’t it be great if Apple included that in the firmware? Imagine that if we have these 40 apps installed, it’s 40 times the same framework consuming space and no need for that. But that’s asking too much, right? :)

Tags:

C# | iPhone

Anonymous delegates and Lambdas

by Brian Keating Mon, February 22 2010 23:47

Just a sample that may catch you eye as unusual..

 

 class WorkItem
{
    public WaitCallback Callback;
    public object State;
    public ExecutionContext Context;

    private static ContextCallback _contextCallback = s =>
    {
        var item = s as WorkItem;
        item.Callback(item.State);
    };

    public void Execute()
    {
        if (Context != null)
            ExecutionContext.Run(Context, _contextCallback, this);
        else
            Callback(State);

    }
}

 but here's the same code using anon delegates

class WorkItem
{
    public WaitCallback Callback;
    public object State;
    public ExecutionContext Context;

    private static ContextCallback _contextCallback = delegate(object s)
    {
        var item = s as WorkItem;
        item.Callback(item.State);
    };

    public void Execute()
    {
        if (Context != null)
            ExecutionContext.Run(Context, _contextCallback, this);
        else
            Callback(State);

    }
}

Tags:

C#

Anonymous delegates and event execution

by Brian Keating Tue, February 02 2010 15:18

A nice little trick to save you always checking for null when firing custom events
Initialize to anonymous delegate.
Ok.. we've an extra call in the invocation list so use judiciously

public event CompleteTaskExecutionHandler CompleteExecution = delegate { };

//or a sample using Lambdas

public event PropertyChangedEventHandler PropertyChanged = (s,p) => { };

 

 

private void Fire()
{
   this.CompleteExecution(...);
}

 

Tags:

C#

Extension Method for Wpf Window with Froms Owner

by Brian Keating Thu, January 28 2010 09:47

 

Extension Method

internal static class InteropExtensions
{
    public static bool? ShowDialog(this System.Windows.Window win, IntPtr handle)
    {
        WindowInteropHelper helper = new WindowInteropHelper(win);
        helper.Owner = handle;
        return win.ShowDialog();
    }
}

 

Usage

var win = new WpfWindow();
win.ShowDalog(windowsFormOwnerHandle);

Tags:

C# | windowsforms | WPF

Key modifiers

by Brian Keating Tue, December 22 2009 22:32

Recently I used PInvoke to check if the SHIFT key was pressed while i was doing a drag operation......

what I should have done then and have done now is

 

if((Keyboard.Modifiers & ModifierKeys.Shift) != ModifierKeys.None)
  Trace.WriteLine("Shift is pressed");

Tags:

C# | windowsforms | WPF

.NET DateTime Webservices UTC

by Brian Keating Wed, December 02 2009 23:18

With .NET 1.1 when we receive a UTC DateTime in a SOAP response from a webservice it used to get converted to Local time.

With .NET 2.0 when we receive a UTC DateTime in a SOAP response it stayes in UTC.

If you need it in local time make sure to call .ToLocalTime()

 

** Edit: P.s. Have a look at this neat class in the framework XmlConvert

Tags: , ,

C# | WCF

Windows Forms Validation

by Brian Keating Thu, November 05 2009 08:53

One approach for validating child controls on windows froms is to

Validation.

  • Add a Validated event handler to all child controls you're interested in.
  • On a button event handler call this.ValidateChildren();

This will ensure the validation routine on all child controls will be called, if for example you've added an ErrorProvider control extender to your form you can set it up in the validated event handlers.

Tags:

C# | windowsforms

Resource Cleanup and Lambda Expressions

by Brian Keating Tue, November 03 2009 18:29

A neat way of always cleaning up resources is to use Lambdas as data.

Take the following

Source

    internal interface ITryCatchReport
    {
        void Try(Action<IServer> action);
    }

    internal class TryCatchReport : ITryCatchReport
    {
        public TryCatchReport(IServer server)
        {
            _server = server;
        }

        public void Try(Action<IServer> action)
        {
            try
            {
                action(_server);
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.Message);
                // Clean up resources
                // Report errors
            }
        }

        private IServer _server;    
    }

 

 

Usage

TryCatchReport safeInvoker = new TryCatchReport(_data.Server);
safeInvoker.Try(x =>
{
 x.MakeInterfaceCall();
}); 

We are now guranteed that in the case of an exception that the resources will get cleaned up.

 

Usage with code blocks

If you wish to execute many statements in the action look at this sample.

 private List<WFActionDefinition> GetActionDefinitions()
{
    if (_actionDefinitions == null)
    {
        safeInvoker.Try(x =>
            {
                x.Do1();
                x.DoSomething();
                OtherFunc();
            });
    }

    return _actionDefinitions;
}

Tags:

C#