Unwanted whitespace in unordered lists using Internet Explorer

I had a drop-down menu which try as I might would not remove the whitespace from between the list item elements for IE. It turns out this is a bug with IE. The solution I eventually found was for IE only which was annoying. You simply need to set the the following style, either in your css sheet or directly:

.myIEclass
{
      ...
      margin-top: -3px;
}

Of course you may find that you need to set margin-left instead, depending on your whitespace.

I found that this issue only seemed to occur if I had more than one child element of my li tag, but whether that is the actual cause who knows? Could be anything with Internet Explorer!

If you don’t specifically target IE then the menu/list will appear squashed in the other browsers. As I was generating this menu via an MVC HtmlHelper I was simply able to target IE directly using the UserAgent property in C#:

HtmlTextWriter writer = new HtmlTextWriter(html.ViewContext.HttpContext.Response.Output);

...

if (HttpContext.Current.Request.UserAgent.Contains("MSIE") == true) //HACK: Lovely IE hack
        writer.AddAttribute(HtmlTextWriterAttribute.Style, "margin-top:-3px");

Of course if you are not generating via a helper you could also use HTML directives such as:

<!--[if IE 8]>
---
<![endif]-->

which is ugly, but a more robust way of doing it than CSS ‘hacks’, which I am not going to discuss here as it might give you bad ideas. 🙂

Advertisements

CS1502 error when creating a new HtmlHelper

When creating my own HtmlHelper class I was getting this error message at runtime (it compiled fine):

CS1502: The best overloaded method match for ‘System.IO.TextWriter.Write(char)’ has some invalid arguments

This was caused by the fact that my helper method had a void return type. I had previously had return types on my own helpers which is why I hadn’t come across this before. To correct the problem you just need change the call to the helper from this:

<%= Html.MyHelper() %>

To this:

<% Html.MyHelper(); %>

i.e. remove the ‘=’ and add the semi-colon at the end. Quite obvious when you think about it, but it is making that connection between the return type of the helper and the required embedding tags in the first place in order for it to become that obvious!

Using Anytime Javascript date/time picker with Internet Explorer

The Anytime date/time picker is very good, but there seems to be a bug using it with Internet Explorer, in that the picker window can popup behind the other controls on the screen.

The way to fix this is to add the following to your css:

#AnyTime--DateRequired
{ 
          z-index:10000;
}

Where ‘DateRequired’ is the name of your textbox (i.e. in MVC Html.TextBox(“DateRequired”,… ).

Setting z-index to a very high value ensures that the popup window will always appear on top.

Locking a record using nHibernate

If you are generating your own reference number, or updating a stock level, or anything that means that you need to make sure that only one person at a time can access that record then you need to lock it.

You can do this in nHibernate with the following example code in your repository; the SetLockMode addition is the key method:

using NHibernate;
/// <summary>
/// Set the specified key in a config table to the specified value
/// </summary>
/// <param name="keyName">Name</param>
/// <param name="keyValue">Value</param>
public void SetKeyValue(string keyName, string keyValue)
{
     NHibernate.ICriteria criteria = Session.CreateCriteria(typeof(MyConfig))
                .Add(Expression.Eq("KeyName", keyName)
                 ).SetLockMode(LockMode.Upgrade);

     MyConfig newConfig = criteria.UniqueResult() as MyConfig;

     newConfig.KeyValue = keyValue;
     SaveOrUpdate(newConfig);
 }

Note that this record is only locked once the process passes the UniqueResult() method, i.e. at the point it returns a value to the program. It is unlocked once the wrapping transaction is committed or rolled back, so if your value is something that needs updating many times a second I recommend trying to minimise the size of that transaction!

nHibernate SaveOrUpdate() not working

nHibernate’s SaveOrUpdate() repository function only works within a transaction! Obvious when you think about it, but how you actually create the transaction with Sharp Architecture in the first place isn’t!

Within your MVC controller class file you need to import the following:

using SharpArch.Web.NHibernate;

Then add the [Transaction] attribute to the controller method that contains the transaction:

[HttpPost]
[Transaction]
public ActionResult Wibble(ViewModel thisView)
{
           ...
}

That’s it. The transaction is committed once the method returns. If you want to rollback (perhaps after catching an exception), then call:

catch (Exception ex)
{
            _myRepository.DbContext.RollbackTransaction();
}

You can also add the [Transaction] attribute to the class itself, in which case every method of the class becomes a transaction.