Window.Close() from XAML

July 1, 2009

It’s been a long time since I last posted. Since then I have been working on my first WPF contract. I have definately drank the cool aid, I love WPF (when MVVM is being used anyway).

One thing I haven’t been able to find any info on is how to close a window from XAML. I tried and tried and then gave up. Until now!

Having discovered the power of Attached Behaviours, I decided to write one that would close a window. All you need do then is create a data trigger that watches a CloseSignal on the ViewModel and sets the Close property to true.

public static class WindowCloseBehaviour
{
public static void SetClose(DependencyObject target, bool value)
{
target.SetValue(CloseProperty, value);
}
public static readonly DependencyProperty CloseProperty =
DependencyProperty.RegisterAttached(
“Close”,
typeof(bool),
typeof(WindowCloseBehaviour),
new UIPropertyMetadata(false, OnClose));
private static void OnClose(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is bool && ((bool)e.NewValue))
{
Window window = GetWindow(sender);
if (window != null)
window.Close();
}
}
private static Window GetWindow(DependencyObject sender)
{
Window window = null;
if (sender is Window)
window = (Window)sender;
if (window == null)
window = Window.GetWindow(sender);
return window;
}
}

and then in your XAML

<Style.Triggers>
<DataTrigger Binding=”{Binding CloseSignal}” Value=”true”>
<Setter Property=”Behaviours:WindowCloseBehaviour.Close” Value=”true” />
</DataTrigger>
</Style>


CI Factory

May 4, 2008

Continuous Integration Factory (CI Factory) has just popped up onto my radar and looks fantastic.

Being currently on hiatus and looking to get into the London contracting scene I have been talking to expats about how much pain to expect. Build process comes up time and time again. I’ve heard of builds being manual and taking whole weekends!! So this looks to be a handy tool to have under your belt for getting CI setup quickly.


A Temporary Hiatus – XMP

April 5, 2008

It’s been about 6 months since I left BluFreeway and took to a life of beaches and relaxation that ones honeymoon brings. :)

The call of coding had nagged me into installing VS 2008 on our lightweight travel laptop to stay afresh of developments in the .NET space. When a small error on my behalf (no prompts for bulk changes in Vista’s Photo Gallery!!) corrupted all the dates of our wedding photos that Kahlia had painstakingly rated, tagged and categorised.

Smiling smugly i said “No Problem!”, knowing all I had to do was whip up some code to copy the dates from the originals we had backed up. A few minutes later I had some code to do such a task. I even knew about EXIF and how to access it. How proud I was off myself knowing all about this graphics stuff! To my dismay the app whilst changing the metadata did nothing towards fixing the problem in Vista. Apparenlty my knowledge was out of date.

Enter Adobes brain child, XMP, a new era in metadata apparently. Thankfully .NET 3.5 has a great set of classes to handle this, WPF. It made the whole process really simple in the end. If only the documentation was as good.

Know it’s back to the sand and surf for awhile yet.


The Evil of ObjectDataSource Overcome….

April 12, 2007

Well for me at least.
I had the need to use the ObjectDataSource but wanted to get the “Business Object” from our IoC container, rather than the default method of the Activator created instance. We needed a stateful object that could modify a list of data objects in volatile storage at our databound controls beck and call. This simple task wasn’t so simple.

<Rant>
The ASP.NET team clearly thinks that they are the be all and end all of software design as most remotely powerful classes are locked down with private or internal modifiers.
</Rant>

Some Googling found this guy who had felt the pain, enough I might add to raise more than a handful of issues with microsoft, all of which were promptly set to a status of “won’t fix”. Sound familiar? Marc solved the issue by creating his own datasource control and view and through heavy reflection has solved his problem.

I was not satisfied with the reflection road so I started develing into the documentation. Previous examples had all been using the “Parameters” method of making updates and deletes. That is they specify in the markup the names and types of the parameters on the Update and Delete methods. This had never impressed me much (I still wish there was an easy way of coding new Class().Method.Name  ;) ) and so when I came across the DataObjectTypeName I found a new path to follow.

Briefly the DataObjectTypeName allows you to specify the type of your actual object that you update, insert, delete etc. The ObjectDataSourceView then uses reflection to bind the Databound controls values to an instance of that dumb object. The dumb object is then passed into the Update, Delete methods of the object that is created from the TypeName property. This lead to the realisation that I only needed 4 methods for an instance of the DataSource control; Select, Update(object item), Insert(object item) and Delete(object item).

I can handle implementing the Proxy Pattern for four methods… so I did.
The ObjectDataSource control specifies the TypeName of the proxy class which using generics allows me to pass the Type of the class i want resolved from the IoC container.
The proxy then just passes of the calls to the real “BusinessObject”.
This solution makes use generics so the type names are too cumbersome to be added to markup (plus I don’t like type names in markup) so I create classes for each datasource I need.

public interface IDataObjectContainer<T>
{
int Delete(T item);
int Insert(T newItem);
IList<T> Select();
int Update(T newItem);
}

public class DataObjectProxy<TContainer, T> where TContainer : IDataObjectContainer<T>
{
private TContainer proxiedObject;

public DataObjectProxy()
{
proxiedObject = ResolveInstance();
}

protected virtual TContainer ResolveInstance()
{
return (TContainer)Activator.CreateInstance(typeof(TContainer));
//return IoC.Resolve<TContainer>();
}

[DataObjectMethod(DataObjectMethodType.Select)]
public IList<T> Select()
{
return proxiedObject.Select();
}

[DataObjectMethod(DataObjectMethodType.Insert)]
public int Insert(T newItem)
{
return proxiedObject.Insert(newItem);
}

[DataObjectMethod(DataObjectMethodType.Update)]
public int Update(T changedItem)
{
return proxiedObject.Update(changedItem);
}

[DataObjectMethod(DataObjectMethodType.Delete)]
public int Delete(T item)
{
return proxiedObject.Delete(item);
}
}

An example of my strongly typed ObjectDataSource is as follows, note the DataObjectSessionContainer and Item classes are missing. They are just proof of concepts, Item is my dumb data object for the example and DataObjectSessionContainer is the implementation that modifies the a list of items in the session.


public class ItemSessionObjectDatasource : ObjectDataSource
{
public ItemSessionObjectDatasource()
{
this.TypeName = typeof (DataObjectProxy<DataObjectSessionContainer<Item>, Item>).FullName;
this.DataObjectTypeName = typeof (Item).FullName;
}
}


Fiddler and .Net Authentication

October 31, 2006

I had an issue recently with in-line java-script not being rendered using AJAX ASP.NET. So I fire up Fiddler to see whats going on. Only when ever fiddler is open the app no longer works, it throws a WebException complaining that the connection was reset or aborted.

We are using Integrated Authentication on a separate server that the app talks to via web services. It turns out by default Fiddler doesn’t get along with the way .Net Web Services authenticate. It closes any connection that returns a 401.

This article explains the problem and the fix (which is to add a custom rule to fiddler to stop it closing the connection)

http://blogs.newsgator.com/inbox/2006/09/fiddler_and_net.html


Setting Bind Private Path

June 19, 2006

We are messing around with Custom Extensions in Reporting Services. Our extensions bring in a number of DLL's that we regularly update and remove as we play with our new toy. The problem is that invariably we delete one of the DLL's that isn't ours… bye bye Reporting Services. :)

After a couple of attempts and a little searching I found out you can indeed set the private probe path (the path you see displayed as "Intial Private Path" if your looking at fusion logs) The CLR binder will then also check this path for DLL's. Thus allowing you to seperate your DLL's from reporting services'… or any other situation that may be more relevant to you.

Whack this into your app or web config. Also notice that it is relative to the application directory.

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin\ECM"/>
</assemblyBinding>
</runtime>


Raising a bug/suggestion for the .NET Framework

May 10, 2006

Ever wondered how to raise a bug/suggestion for the .NET Framework? I have. And I finally came across it here

http://connect.microsoft.com/feedback/default.aspx?SiteID=210
We encountered a breaking change from 1.1 to 2.0 with the RadioButtonList and raised it here.


$exception; exceptional

May 10, 2006

I have been using Visual Studio 2003 since the first beta. Until today however, I never knew about $exception. This post is a reminder to me that the Locals Window is my friend.

There is a local variable in the locals window when the debugger breaks due to an unhandled exception that holds the thrown exception. I cringe at the thought of time wasted trying to get the same information via other, shall we say less effecient, means.


Bang! Bang! your dead

February 23, 2006

I found an obscure bug today, a typo no less, but Im getting ahead of myself.
It turns out that C# allows you to use multiple not operators (!).

So:  true == !!true and false == !!false

Why you would ever want to use this is beyond my small level of comprehension, but it made finding my bug a little harder.

if(!X and !!Y) then do something

it turns out it was meant to be
if(!X and !Y) then do something

The double bang is easily glossed over as your eyes are looking for its presence not checking there is a correct count of bangs.