Monday, January 26, 2009

Neat way to handle Nullable types ...

Ever since I read Rick Strahl's blog post on the C# ?? operator, I've been in love with the C# ?? operator. Mostly I use it as a clean way to test a ViewState variable for null in a property. For example,

protected string stringToPersistOnPostBack {
   get {
      return (ViewState[this.ClientID + "_stringToPersistOnPostBack"] ?? "").ToString();
   }
}

Somewhere along the way, the real purpose of the ?? operator was forgotten though. It's true purpose is to give a default value to a Nullable type thus allowing you to use it as the type.

I started with this code:

bool doExpand = (IsPostBack && e.Node.Expanded);

which gave me an error: "Operator && cannot be applied to types 'bool' and 'bool?'"

While I often enjoy the use of Nullable types, they do introduce often annoying, sometimes unnecessary complexity to code. But thankfully, the nice folks at Microsoft came up with a rather nifty solution ... the ?? operator.

At first, I thought I'd have to use the ?? operator to give e.Node.Expanded a default value of false AND cast the object to bool. Instead, all I had to do was this:

bool doExpand = (IsPostBack && (e.Node.Expanded ?? false));

See? Neat!

Thursday, October 9, 2008

Web Dev Best Practices

This has come up in various conversations recently and I was bored so I was googling for html best practices. I thought this article from Apple was quite good.

Tuesday, September 30, 2008

Forcing ASP .Net Validators and ValidationSummary to use CssClass

Here's something strange. If I create a validator using the following mark up:

<asp:requiredfieldvalidator id="rfv_txt" runat="server" errormessage="Required" CssClass="errorText" />

and my css class is:

errorText {
color: purple;
}

My validator still renders with red text. Checking the markup, I see that ASP .Net has added an inline style attribute (style="color: red"). Obviously, inline styles take precedence over class styles. But why is this inline style being applied at all?

I found this blog post that fixed the issue by setting the Forecolor to Color.Empty but it could only be done server-side. I figured there must be a way to set this client-side and after much annoyance, I found it:

<asp:requiredfieldvalidator id="rfv_txt" runat="server" errormessage="Required" CssClass="errorText" Forecolor="" />

So in order to set the color of validators or ValidationSummary via a CSS class you must set both the CssClass property and set the Forecolor property to an empty string. Why ASP .Net? Why?

Friday, August 1, 2008

WPF Data Binding Not Refreshing When Bound to Static Object

And the WPF Data Binding wierdness/frustration continues ...

I have a DataTemplate where DataType is defined. (In other words, WPF magic figures out when to use the template based on the type that is being bound). The Template includes a ComboBox which is bound to a static object in my UserControl class. The SelectedItem of the combobox is bound to a property of the DataTemplate's type (which, in this case, is a linq entity object).

It looks something like this:



My problem was that when I changed the DataContext of the UserControl which in turn changed the DataContext of this DataTemplate's parent control and the DataTemplate itself, the data in the ComboBox didn't change. In other words, while all the controls around it were being re-bound, this particular control wasn't.

Grrr.

After much googling, I found a cheap - but helpful - solution. Force the ComboBox to rebind every single time but adding a IValueConverter (which does nothing but return the value) to the binding.

Here is the article with the solution.

Seriously, these WPF Data Binding issues are ridiculous. I mean what exactly was Microsoft testing this shite for? It surely wasn't real-world examples or even with it's own new technology (Linq to SQL for example).

Thursday, July 31, 2008

Type casting your User Control Class in ASP .Net 2.0+

I ran into a little bit of a strange issue today:

I created a User Control that was being used multiple times on a page. It contained a few public methods and properties that allowed me to delegate loading and saving of the data to the control.

Since I have a personal aversion to typing out the same thing for controls with different names, I wanted to just loop through the Controls, check for the type, cast, and call the method. Seems simple right?

Not so much.

First I had a bit of trouble getting the actual type to cast. I googled and found a solution:

((ASP.controls_myControlName_ascx) myControl1).LoadMethod();

Super. The code ran just dandy on my local machine.

However, I ran into a bit of trouble when we deployed the code to our testing environment. It couldn't figure out what ASP.controls_myControlName_ascx. Of course, this happened when my internet was down and I was working at home and everyone was freaking out.

To fix the deployment issue, first, I got rid of the "ASP." prefix. Then it wouldn't compile on my local machine. Bah.

In googling, I came across this article: Understanding Page Inheritance in ASP.Net 2.0 by Rick Strahl. I used his solution for Pages and created an abstract base class which inherited from UserControl and contained abstract public methods. I put the abstract class into the App_Code folder and wa-la! I could cast the controls to the base class and call the methods and set public properties. Yay!

Sort of. It's actually kind of a lame solution but it works and is acceptable.

Tuesday, May 27, 2008

Random Annoying Crap about WPF Data Binding & Linq to SQL

For a new project at work, we are using WPF and Linq to Sql. In some ways data binding in WPF is very sexy and suave. In other ways, it's aggravating - there are things that are so easily done in WinForms and ASP .Net, like, say, re-binding data to a control after it's changed, that are bitch to figure out in WPF. At least for me they are.

In theory, WPF can update itself whenever the source changes. In reality, it's not quite as simple as it sounds.

First of all, if you happen to be extending the generic ObservableCollection and have a method in your new class that adds items to the collection, using the Add() method will update the control while using Items.Add() will not update the control. Why? Who knows?

public class ObservableStringCollection : ObservableCollection
{
public ObservableStringCollection()
{
Add("First");
Add("Middle");
Add("Last");

}

public void AddMe(string s)
{
Add(s); //I notify controls I'm bound to!
Items.Add(s); //I don't notify!
}
}


Secondly, Linq to Sql is not observable so anytime you SubmitChanges(), any control bound to your Linq classes doesn't get updated. I got around this by re-setting the ItemsSource property. Ok, fine. Here's the strange part: using ToArray() on the Linq collection will set the source correctly, while using AsEnumerable() will not set the source correctly. AsEnumerable() will set the source correctly the first time it's bound.


tvPages.ItemsSource = CMSUtility.DataContext.CMS_Pages.ToArray(); // I work!
tvPages.ItemsSource = CMSUtility.DataContext.CMS_Pages.AsEnumerable(); // I only work the first time!


Currently, I'm working on extending the Linq DataContext to be somewhat observable.

I wrapped the Linq DataContext class and implemented the INotifyPropertyChanged interface. Then I overrode the SubmitChanges method to fire the notification event.

public class ObservableDataContext : LinqClassesDataContext, INotifyPropertyChanged
{
public ObservableDataContext() : base("Data Source=.;Initial Catalog=DB;Integrated Security=True") { }

public ObservableDataContext(LinqClassesDataContext dc) : base(dc.Connection, dc.Mapping.MappingSource) { }

public override void SubmitChanges(System.Data.Linq.ConflictMode failureMode)
{
base.SubmitChanges(failureMode);
NotifyPropertyChanged("Nodes");

}

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

public void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}

#endregion
}
}

This way I can attach an event to the PropertyChanged for classes that I bind with.

That's the theory anyway. In practice, it's *sort of* working - I am able to get the Linq SubmitChanges to notify my source object and rebind to my control. However, when it binds to the control again, it doesn't use my DataTemplates. That's for another post I guess.

I'm off to yoga ...

Monday, May 12, 2008

DBNull is my Nemisis: Part Deux

******
This is the second part of my rant about DbNull. Go here to read the first part.
******

Ok. So now you have a utility method that lets you check for null whether it's null, DbNull, or, if bound to a datagrid, "&nbsp;"

What if you want to Convert that object, which might be null or DbNull, to a Type? What if you'd like to write it in pretty code? Well then you'd use this lovely method:

public static T ConvertToType(object o)
{
if (o == DBNull.Value || o == null)
return default(T);
return (T)o;
}


There are few things to note about this method. The first is that it will throw an exception if o can't be cast to type T. This very possibly might be what you want.

The second thing to note is the use of default(T). The default method is a useful little thing that allows .Net Generics to work with both value (structs) and reference (class) types. Basically, default(T) will return the default value of a value type, i.e. 0 for int or System.Int32, or null for a reference Type.

What if you don't want the method to throw an exception when converting? What if you'd like to use the equivalent to the "as" operator?

You might replace the last line of the method with this:

return o as T;


Then you would get a compiler error. Why? It's quite simple really. The "as" operator only works on reference types because only reference types can be null. One solution to this problem is to return default(T) if the casting fails.

public static T ConvertToTypeOrDefault(object o)
{
try
{
return ConvertToType(o);
}
catch (Exception e)
{
//this will return null for nullable types & the default value for non-nullable types
return default(T);
}
}


However, what if you really really want the convert method to return null. The short answer is that you can't; the long answer is that you can. :)

While you can't make a method that could return value types return null, you can force the method to only take certain Types using Generic constraints. In this case, we'd want the method to only accept reference types.

I tried to get this to work using a variety of methods until my trial and error finally ended in success. First, I tried returning T? (i.e. Nullable) but since reference types are already Nullable and Generic Nullable class only takes value types. Bah. So I tried restricting T to System.Nullable. Nope - static classes can't be used as constraints. Then, I tried restricting T to System.Object. Nope - Object is a special class and can't be used in this way. (Awww, it's special) . Next, I tried constraining T to new(), which essentially constrains T to classes that have a default constructor. Still nada - constraining to new() had no effect on the compiler erroring when I tried to return null.

Finally, after skimming the MSDN introductory article on Generics, I landed on the solution! T can be constrained by "class" (and conversely, by struct).

public static T ConvertToTypeOrNull(object o) where T : class
{
if (o == DBNull.Value)
return null;
return o as T;
}



Viola!

It's true that the ConvertTypeToDefault method is essentially the same for ConvertTypeToNull when T is a class. One advantage of using the ConvertTypeToNull is that it doesn't require the overhead of exception handling.

Thinking about default and value types brings up another issue though: What if you want to know if something is null OR if it's the default value. In other words, you are converting the Potential-DbNull object to a struct and want to know if it has no value.

You could add an additional method:


public static bool isNullOrDefault(object o)
{
bool bIsNull = isNull(o);
if (!bIsNull && o is ValueType)
{
bIsNull = ConvertToType(o).Equals(default(T));
}
return bIsNull;
}

public static bool isNullOrDefault(object o, bool webBound)
{
bool bIsNull = isNull(o, webBound);
if (!bIsNull && o is ValueType)
{
bIsNull = ConvertToType(o).Equals(default(T));
}
return bIsNull;
}


Something to note is that I'm not using the == operator to compare the default type with what's returned by ConvertToType. Why? Simple - the compiler doesn't let me. Again, because at compile-time the type that T represents is ambiguous, the compiler doesn't know if T supports the use of the == operator so it complains. Fortunately, the Java style .Equals method, while a bit ugly, does the trick just fine.

Also, the above method will throw an exception if the object can't be converted to the type. It seems logical to me, but you could use a different ConvertToType* method if you wanted.

(If you want to know more about what the webBound bool is for, check out my first post on DbNull.)

So there you have it! A DbNullUtility class to make your life just a little bit easier. Hooray for me and fuck DbNull! (Bad Religion anyone??)