Wix and the TFS 2013 build server, let's be friends

We recently commissioned a new build server as part of an upgrade and moved to WiX 3.9R2 as part of the process. After setting up a new build profile my installer build would fail with this same message per each ICE action:

light.exe (0): Error executing ICE action 'ICE01'. The most common cause of this kind of ICE failure is an incorrectly registered scripting engine. See http://wixtoolset.org/documentation/error217/ for details and how to solve this problem. The following string format was not expected by the external UI message logger: "The Windows Installer Service could not be accessed. This can occur if you are running Windows in safe mode, or if the Windows Installer is not correctly installed. Contact your support personnel for assistance.".

Which produces a similar message in the server's event logs:

Product: ProductNameRemoved -- Error 1719. The Windows Installer Service could not be accessed. This can occur if you are running Windows in safe mode, or if the Windows Installer is not correctly installed. Contact your support personnel for assistance.

At this point much googling leads to to a similar set of instructions, re-register msiexec, check registry permissions, etc. I tried all of these to no avail, until finally I came across an insightful post from John Robbins that has the solution:

"In order for the .WiXProj files to compile, the account running the build controller/agent must be in the local machine’s administrator group."

Therefore the solution is simply:

  1. Add the service account to the Local Administrators user group
  2. Restart the server
  3. ...
  4. Profit!

Note: If you do not already have a service account then I strongly advise you to create one, it is a dangerous security practice to run add a low privileged account like NT SERVICE as an administrator.

Categories Software Development | Tagged dev, error1719, error217, tfs, tfs2013, tfsbuild, wix, wix-3.9

DesignData makes your life easier

Intro

Okay so I have finally jumped onto the band wagon and decided to apply my skills to Windows Phone development - after all I've had a Windows Phone since launch and I am a .NET developer. So really it's about time.

I won't go into the basics of how to start coding a Windows Phone application, the Windows Dev Centre really have that covered with a good variety of simple articles. What I will say however is that with XAML/Silverlight and a C# back-end, coding for Windows Phone is much like a marriage between ASP.NET and Win Forms, and a good one at that.

And without further adieu...

On with the show

Soon enough after jumping into creating your first application, hopefully you are going to discover of the MVVM design pattern and start binding your controls to properties in a ViewModel. Or regardless binding your controls to an object of some kind.

Here's where there is a bit of a Gotcha moment, as you clear the dummy values and bind to the controls and for the most part discover that your interface is rather, well, blank. All of those lists and textboxes are not only empty but is most cases not visible at all.

If you are like me it is at this moment you go looking in the IDE for a suitable property to add testing data to, as seeing your UI in the Designer can sometimes be useful. And then there is the next Gotcha, there isn't one.

Microsoft in their wisdom, most likely to confuse developers, have not made it so easy for us. But have no fear there is a way, or truth be told a few, to add some test data to your design time UI.

Option #1: FallbackValue

By far the easiest way to achieve this to specify a FallbackValue in the actual binding on the control. This will set a value to the control if the bound value is not available.

<HyperlinkButton Content="{Binding FooterText, FallbackValue='Foo Bar'}" />

However the drawbacks of this method are that this value will also be shown at runtime if you have no bound value, and it won't do much for any control that expects a collection be bound to it.

Option #2: Create a DesignData file

The next best option is to create a specific DesignData file that represents your ViewModel and contains data to be shown only at design time. This file will be written in XAML and allows you to set values for any of the public properties in your ViewModel, including any dependant types.

Now of course you could also use this method for any object you intend to set as the DataContext of a page or control, the method is much the same.

What you need to do in short is:

  1. Create a text file and name it with a .xaml extension.
  2. Add XAML representing your ViewModel (see below)
  3. Set the BuildAction to DesignData, and clear the CustomTool property
  4. In your control/page, ensure that the same namespace is also defined in your control/page's tag
  5. Add a property to your PhoneApplicationPage (or any Control) referencing your new xaml page

    d:DataContext="{d:DesignData Source=/DesignData/MyViewModel.xaml}"

  6. Then bind the control as you would normally.

Creating the XAML DesignData file

<local:MyViewModel xmlns:local="clr-namespace:Badmonkeh.ViewModels">
   <MyViewModel.Items>
      <local:MyViewModelItemCollection>
         <local:MyViewModelItem Name="One two three four" Colour="Blue" PercentComplete="75" ShowProgress="True"/>
      </local:MyViewModelItemCollection>
   </local:MyViewModel.Items>
</local:MyViewModel>

In this particular example I am representing a class named MyViewModel which has a MyViewModelCollection in a property named Items. This in turn contains a MyViewModelItem in its default property.

This is pretty standard XAML here, each property of a simple type is a simple key-value pair and each complex type must be described with a new XML element. Where a property for a complex time is not the default content property, a separate element must be created a referenced using the name of the parent class, e.g.

<MyViewModel.Items>

The important things to note here:

  • The declaration of the namespace corresponds to the class's full name
  • Generic lists are not supported so you will have to extend your own collection
  • Your ViewModel must have a public parameter-less constructor
  • Only properties with backing fields can be bound (see below).

A caveat and a solution

There is a caveat to this method, inherent in its design. What actually happens when you create a DesignData method is that the designer will create an instance of your class at design time where certain objects may not be available such as your data model, or IsolatedStorage.

The easiest away around this is of course to  simply use properties with backing fields but when that is not convenient you can get around this by checking if you are in design mode by calling DesignerProperties.IsInDesignTool and using a backed field only for design time.

public string Comment
{
    get
    {
        if (DesignerProperties.IsInDesignTool)
            return _designerComment;

        if (_blog == null) return null;
        return _blog.Comment;
    }
    set
    {
        if (DesignerProperties.IsInDesignTool)
            _designerComment = value;
        else
            _blog.Comment = value;
    }
}

In the example you can see that I check if we're in the designer (or Blend for that matter) and use a backed field to avoid throwing an exception which would disable the design data, or returning null which would just disable the property.

You might of course wonder why go to the trouble of using a backing field when I can just return a testing value in the property? Well you're right, you can. However this will override any value you specify in the design data XAML file and if this class is shared with other pages, for instance if is used by a User Control, then you won't be able to create separate design data files for different pages.

Conclusion

I have shown you a couple of ways to shows some design time data in your pages and help simplify the design process somewhat. The particular beauty of the second approach is that you can design your Control/Page first and really just consider the fields that you will need to bind to. At the time you just need to create a POCO class and only after the design is finalized implement your business logic.

Regardless I hope some of this was useful to you and if not, or if there is anything else I missed, hit me up in the comments below.

Categories Software Development | Tagged .net, c#, design, DesignData, dev, silverlight, wp7, wp8, xaml

Active Records with Partial Trust, Revisited

Active Records with Partial Trust, Revisited

Getting active records to run under medium trust is a problem i have once solved before, and after upgrading to v2.1.2 it has come back again. Essentially the problem is two fold:

  1. Ensuring all referenced Castle assemblies has the APTCA attribute applied
  2. Statically generating proxies with the APTCA attribute applied (is this still necessary?)

To begin i need to identify which assemblies are the problem. So i created a small test project and noted the assemblies that were directly or indirectly used, using Reflector. At the same time i could go through the list and note which ones did not have the attribute applied. This lead to the following list.

Referenced Assemblies Without APTCA:

  • Castle.Core (1.2.0.0)
  • Castle.Components.Validator (1.1.1.0)
  • Castle.ActiveRecord (2.1.2)

Now in order to call these assemblies under medium trust i will have to rebuild them, applying the correct attribute, this could be quite a problem but fortunately Active Records is an open source project. After a short search i discovered that the source is now stored at Github: http://github.com/castleproject

Then it was a simple case of downloading the source, labeled at the appropriate versions listed above.

This however seemed to be more trouble that it was worth, given that the code was hard to build when it was first split into individual projects (read: required Nant and i couldn't be bothered.)

Building the projects from source was simple enough when you copy in the buildscripts\ folder from the root project 'castle'. You might have manually reference the key to get them strong named but this is a simple matter.

From here all you have to do is apply the attribute as below to the CommonAssemblyInfo file, and voila you are done.

[assembly: System.Security.AllowPartiallyTrustedCallers]

If your website is just a personal site and you do not have strongly name assemblies, then this is all you need to do.

Step 2 is the harder part. Assuming your assemblies are strongly signed, ensure first that they also have the APTCA.

Categories Software Development | Tagged active records, castle, partial trust

Upgrading Castle Active Records

Upgrading Castle Active Records

From 1.0.3.0 (custom build) to 2.1.2

Downloaded binaries from http://sourceforge.net/projects/castleproject/files/ActiveRecord/2.1/AR%202.1.2.zip/download

I downloaded the binaries, and replaced my reference libraries. To my surprised there were no build errors.

Intrigued, i wandered onto the documentation to see what new features/syntax i could use. Some notable things i found:

You can now initialise active records by just supplying an assembly, and letting it reflect the types for you.

ActiveRecordsStarter.Initialize(Assembly assembly, IConfigurationSource source)

Warning: Try to create an Assembly exclusively for ActiveRecord types if you can. This overload will inspect all public types. If there are thousands of types, this can take a considerable amount of time.

Some validation attribute (Validators):

ValidateIsUnique,ValidateRegExp,ValidateEmail,ValidateNonEmpty,ValidateConfirmation

Generics support:

extend generic base class ActiveRecordBase<T> or for inherent validation support extend ActiveRecordValidationBase<T>

Note however that if a record is invalid and you try to save it, it will throw an error. Be sure to check it's IsValid method first.

What doesn't work is my proxy class generation.

So i decided to upgrade to using the NHibernate Proxy Generators (http://sourceforge.net/projects/nhcontrib/files/NHibernate.ProxyGenerators/1.0.0%20Alpha%20564/)

Here's a how to: http://nhforge.org/wikis/howtonh/pre-generate-lazy-loading-proxies.aspx

Unfortunately i had the same issue as last time, that it just does not work for NHibernate 2.2

So i decided to have a play around with the source code a little.

  • Converted the project to VS2010.
  • Deleted all in libs except for IlMerge.exe
  • Pasted new AR libs in there
  • Set all projects target to .NET 3.5

CastleStaticProxyFactory - commented out //using NHibernate.Proxy.Poco.Castle; - replaced with NHibernate.ByteCode.Castle - changed CastleLazyInitializer to LazyInitializer

CastleProxyFactoryFactory : IProxyFactoryFactory - added stub method for ProxyValidator

CastleStaticProxyFactoryFactory - added stub method for ProxyValidator

Had to add reference to NHibernate.ProxyGenerators.ActiveRecord to the console project

Commented instantiation of SessionFactory - is this the right thing to do?

CastleProxyGenerator - commented out //using global::Castle.DynamicProxy; + we want to use the new ProxyGenerator v2 - added using Castle.DynamicProxy; - changed ModuleScope to save weakly named assembly only (to avoid an error) - moduleScope.SaveAssembly(false); + for some reason a strongly named assembly doesn't contain the factory classes? - added compiler reference - references.Add(Assembly.Load("NHibernate.ByteCode.Castle"));, also Castle.ActiveRecord - altered the compilation to add the input assemblies as references to creating the StaticProxyFactory

Removed Post Build Event:

"$(SolutionDir)libs\NHibernateProxyGenerator\NPG.exe" /in:"$(TargetDir)BadMonkeh.DAO.dll" /out:"$(SolutionDir)BadMonkeh.Website\bin\BadMonkeh.DAO.Proxies.dll"
copy "$(TargetPath)" "$(SolutionDir)BadMonkeh.Website\bin\$(TargetFileName)"
Categories Software Development | Tagged active records, castle

Catching unhandled exceptions at the lowest level for all threads

Catching unhandled exceptions at the lowest level for all threads

When designing a responsible application it always pays to think about exception handling. Of course it is good practice to not use "catch-all" exception blocks as this makes it easier to find bugs within the system. However when a user invariably finds one, you ideally don't want your application to just crash. You may wish to show them a pretty dialog, or in the very least log the exception details to help you fix it.

If you only ever use a single thread in your application then you can get away with the below:

try
{
    Application.Run(new MyApp());
}
catch (Exception ex)
{
    //handle error here
}

This happens to work well, however what if you are using separate threads to do processing so that you don't tie up the UI? These events will never be handled by this handled, and hence will crash your app.

The solution however is not that difficult. There are likely a few ways you could go about this but this one seems the easiest to me.

static void Main()
{
    // this event handler works for all threads BUT the main thread
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
    // this event handler ONLY works for the main thread
    Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
    // this ensures that the handler will ALWAYS get the event and so can't be reconfigured in the app.config
    // this may or may not be applicable to you
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    Application.Run(new MyApp());
}

private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
    HandleUnhandledException(e.ExceptionObject.ToString());
}

private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
    HandleUnhandledException(e.Exception.ToString());
}

private static void HandleUnhandledException(string exceptionMessage)
{
    //log exception and show dialog here

    Application.Exit();
}
Categories Software Development | Tagged c#, exception

Line highlighting in a RichTextBox

Line highlighting in a RichTextBox

I often find myself writing little tools to perform specific purposes, as is the wont of a programmer.

However, mostly out of laziness, i tend to avoid writing command line utils and instead prefer little GUI apps. They allow me to add features that i can't have with a CLI, such as persisting settings and allowing file selection dialogs.

Anyways, one of the easiest ways to adapt a console app is to create a windows forms app that features a text box containing the output of whatever you wish to achieve. Now this itself is quite easy to do, however it is just as one dimensional as a console app. Why, you may ask, it is because you are still limited to displaying text in one colour. Should you wish to clearly identify your output you are limited to formatting the position or the characters of the text, which can be quite limiting. For example what if you wanted the errors in a process to be more visible that informational messages?

The solution is to use a RichTextBox. It allows you all of the rich text formatting of a rudimentary RTF editor, such as Wordpad. You could even display HTML in it.

Now, you could change your input to have the appropriate HTML/RTF tags, but this is a quite heavy handed approach and requires you to combine the format with the data. All i really want is to be able to change the colour of text as i insert it, quickly an easily. And here is a method to just do that:

    /// <summary>
    /// Appends a log message and highlights it with the specified text colour
    /// </summary>
    /// <param name="message">The message to append</param>
    /// <param name="colour">The colour to display the text in</param>
    private void AppendAndHighlightLogMessage(string message, Color colour)
    {
        int startIndex = txtLog.Text.Length;
        txtLog.AppendText(message + Environment.NewLine);
        txtLog.Select(startIndex, message.Length);
        txtLog.SelectionColor = colour;            
    }

In this example we have a RichTextBox named txtLog, and we are appending a string to it and highlighting only that with the colour specified.

It is important to note that you call the AppendText(..) method. If you just set the text using txtLog.Text += message; this will not work!

One of the nice things about this approach is even though you are only 'highlighting' the text, the colour will remain.

Categories Software Development | Tagged RichTextBox

Creating a custom databound control with postbacks

Creating a custom databound control with postbacks

/// <summary>
/// Creating a custom databound control with postbacks
/// --------------------------------------------------
/// This class provides you the basis for a databound custom control
/// and shows you where to place logic to ensure the data is saved in
/// the ViewState and the dynamically created child controls work
/// as intended
/// </summary>
class MyControl : Control
{
    private object datasource;
    //CF: A list we are using for example
    private RadioButtonList _List;

    //CF: Define this as whatever you want if this control is databound
    //    This object should not be persisted as you are relying on ViewState
    public object DataSource
    { 
        get { return datasource; }
        set { datasource = value; }
    }

    //CF: This variable holds the number of items that were databound
    //    It is used on post back to recreate the items that are stored in the ViewState
    private int NumberOfItems
    {
        get
        {
            if (ViewState["NumberOfItems"] == null)
                return 0;
            return (int) ViewState["NumberOfItems"];
        }
        set { ViewState["NumberOfItems"] = value; }
    }   

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        //CF: The controls must be created here otherwise the postback data will not be loaded!!!
        EnsureChildControls();

        //CF: If your control requires ControlState uncomment this line
        //Page.RegisterRequiresControlState(this);
    }

    protected override void CreateChildControls()
    {
        //CF: Only create the list and it's items here it will be populated on databinding, or via viewstate
        _List = new RadioButtonList();
        for (int i = 0; i < NumberOfItems; i++)
        {
            ListItem item = new ListItem();
            _List.Items.Add(item);
        }
        Controls.Add(_List);

        //CF: Setting additional properties of the controls should be done *after* 
        //    they are added to Controls collection. This will "dirty" the ViewState
        //    and ensure their value is persisted
        //    Ensure you give your dynamic controls an ID, to associate them to their 
        //    ViewState data
        _List.ID = "list";
    }

    protected override void OnDataBinding(EventArgs e)
    {
        //CF: You need to set the number of items here
        NumberOfItems = DataSource.Count;

        //CF: As the list was already created in OnInit() with no items, it must be recreated here
        Controls.Clear();
        CreateChildControls();

        //CF: Now we loop through each item and databind it's actual value
        for (int i = 0; i < NumberOfItems; i++)
        {
            ListItem item = _List.Items[i];
            //TODO: Obtain the value from the DataSource and set the Controls properties
        }
    }

    //CF: If necessary override Render() to specify custom control rendering, otherwise leave it as it is
    //protected override void Render(HtmlTextWriter writer)
    //{
    //  //TODO: Do stuff
    //}

    //CF: If you are using control state uncomment the following 2 paragraphs and customise them 
    //    as necessary. If you need to save multiple objects it is probably best to wrap them up
    //    in a struct/class.
    //    Remember all objects must be Serializable.
    /*
    protected override void LoadControlState(object savedState)
    {
        object[] state = (object[]) savedState;
        base.LoadControlState(state[0]);
        MyObject = state[1];
    }

    protected override object SaveControlState()
    {
        object[] state = new object[2];
        state[0] = base.SaveControlState();
        state[1] = MyObject;
        return state;
    }   
    */
}
Categories Software Development | Tagged asp.net, control, postback

Creating controls that contain other controls (at design time)

Creating controls that contain other controls (at design time)

I oft wondered how to create controls that accept static controls (defined in the .aspx page at design time) as content. This is very useful for designing the "look" of the output, especially in a databind control such as a repeater. There are 2 parts of this.

  1. Adding controls to a collection at design time. An example of this would be a DataGrid's Columns property. e.g.

<asp:DataGrid> <Columns> <asp:Column /> <asp:Column /> </Columns> </asp:DataGrid>

These Column controls will be instantiated at runtime and added to the DataGrids Columns collection. To see how this works lets examine the code for the DataGrid property:

[MergableProperty(false), DefaultValue((string) null), PersistenceMode(PersistenceMode.InnerProperty), WebSysDescription("DataControls_Columns"), Editor("System.Web.UI.Design.WebControls.DataGridColumnCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), WebCategory("Default")]
public virtual DataGridColumnCollection Columns
{ get; }

Now i have omitted the actual code of the property as it's not relevant, what is relevant is the attributes. However, notice that a set property is not even defined. How is that possible? The key attribute here is PersistenceMode. This property defines how a property is persisted to HTML at design time. Let's have a look at all the available values:

public enum PersistenceMode
{
    Attribute,
    InnerProperty,
    InnerDefaultProperty,
    EncodedInnerDefaultProperty
}

Now by default all of the properties of your server control will be specified as Attribute. As the name implies this property will be accessible as an attribute from your controls tag.

The one we are interested in is InnerProperty. This means that your property will be rendered as an element with your controls tag, this is exactly how a the Columns collection works on a DataGrid! If you add [PersistenceMode(PersistenceMode.InnerProperty)] to a strongly type collection, then voila! You will be able to add strongly typed controls to your collection at design time.

Oh and for completion the other 2 enum values allow you to specific that a particular Property will be default value of a tag. i.e. The value between the opening and closing tag of your control, just like a Label. The second just implies that the value will be HTML encoded.

Note: In order for this to work properly your control must extend from UserControland not Control :)

  1. Creating a dynamic templated control to contain other controls

Surprisingly there isn't a whole lot of information out there that is specific to this particular example. In this case i want to have a control that can contain other controls, without having an .ascx file.

If you just want a container and no data-binding then this is actually quite easy to do. I'll show you my code and then go through it:

``` public class TestTab : UserControl { private PlaceHolder _ContentPlaceHolder; private ITemplate _ContentTemplate;

    [PersistenceMode(PersistenceMode.InnerProperty)]
    [TemplateInstance(TemplateInstance.Single)]
    public ITemplate ContentTemplate
    {
        get { return _ContentTemplate; }
        set { _ContentTemplate = value; }
    }

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        if (_ContentPlaceHolder == null)
        {
            _ContentPlaceHolder = new PlaceHolder();
            this.Controls.Add(_ContentPlaceHolder);
        }

        _ContentTemplate.InstantiateIn(_ContentPlaceHolder);
    }
}

```

Okay, first you need to create a class that extends from UserControl. You can instead extend from Control if you like, but you have to implement the interface INamingContainer. This interface does not actually have any methods, it just signifies to the framework that this control will become a naming container. This just means that the controls within ours will have unique id's, which is more applicable to a repeating control but i digress.

Next add a PlaceHolder to hold the template for obvious reasons. Then create an ITemplate property. The important thing to note here is that you set the PersistenceMode (as defined above) so you can easily set it's contents declaratively.

Also the TemplateInstance.Single attribute value as it allows you to reference the templated controls directly within the page.

Finally the real meat of it. In the OnInit event you need to create the content place holder to store your contained controls and add it to the control tree. It is important that you do it in this event so that ViewState is enabled for your sub controls.

The crucial line after that is that you instantiate the templated controls into your place holder. This will replace the place holder with whatever controls were in the template.

I have not tested the ViewState of this, but it should all work.

Note, if you do wish to create templates with values please see the MSDN article: http://msdn.microsoft.com/en-us/library/36574bf6(VS.80).aspx

Note2: Ensure the controls are create in Init to access them in PageLoad (otherwise they'll be created in PagePreRender)

REF: http://www.csharper.net/blog/containerusercontrols_usercontrolsthatcancontainothercontrols.aspx - Comment by Ego

also of interest: http://msdn.microsoft.com/en-us/library/aa478964.aspx, http://msdn.microsoft.com/en-us/library/aa479300.aspx

Categories Software Development | Tagged asp.net, control

Adding a reusable pop-up box using jQuery and ASP.NET

Adding a reusable pop-up box using jQuery and ASP.NET

Using jQuery it is simple to create and show a modal pop-up box with transitional effects. For this guide i sue the code from http://yensdesign.com/2008/09/how-to-create-a-stunning-and-smooth-popup-using-jquery/, but implement it in a reusable way.

Please note that this works perfectly in Firefox and IE7. To get this to work in IE6 you must set the document type to HTML 4.01 STRICT! Don't blame me, blame Microsoft for their buggy software.

Now if you have not already done so i'd advise you to create a ClientScriptHelper class to handle loading javascript classes.

In particular i created methods to load jQuery from the google website, and to load the popup.js which will get into detail below:

public static void RegisterJQueryRemote(Page page)
{
    page.ClientScript.RegisterClientScriptInclude("jQuery", "http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js");
}

public static void RegisterPopup(Page page)
{
    page.ClientScript.RegisterClientScriptInclude("popup", page.ResolveClientUrl("~/jscripts/jQuery/popup.js"));
}

These methods are just a convenience and allow us to programmtically register the required javascript, if you prefer you can register the scripts yourself manually.

Now the javascript required for all the loading, hiding and transitional effects i extracted from the above guide and massage to suit my purposes. This i store in a javascript file popup.js as mentioned above.

This code has been made generic to enable to easily create a popup on any page, however is only designed for a single popup. If you were to have multiple popups you would need to modify the javascript.

Okay so presuming you have installed the script on your own server the steps to implementing your own popup are as follows:

  1. include jQuery and the popup.js Personally i call the above methods in the Page_Load event

  2. create a div with a class "popup", and into this place the code for your popup, e.g.

```

```

  1. create a div with class "backgroundPopup" This just needs to be empty, and will be used to dim the background

  2. Add a div/span called "popupButton" and put a link or button inside it. This will be used to launch your pop-up.

<div id="popupButton"><a>Reject</a></div>
<span id="popupButton"><input type="button" value="Reject"/></span>

  1. And finally add the required styles.

``` #backgroundPopup { display: none;
_position: absolute; /* hack for internet explorer 6/ position: fixed; height: 100%;
width: 100%;
top: 0;
left: 0;
background: #000000;
border: 1px solid #cecece;
z-index: 1; }
#popup {
width: 300px; margin-top: 5px; padding-bottom: 5px; display: none; _position: absolute; /
hack for internet explorer 6*/ position: fixed; z-index: 2; height: 100px; } #popup div { background-color: #E6E6E6; width: 100%; height: 30px; padding-top: 5px } #popup p { margin: 5px; } #popupClose { padding-right: 5px; float: right; font-weight: bold; }
#popupClose:hover { cursor: pointer; } #popupButton { width: 100%; margin-top: 5px; }

.help_titles
{
    border: solid 1px #B5B6B5;
    background-color: #F7F7F7;
    font-family: Verdana, Arial;
    font-size: 11px;
    color: #1C1F7B;
}

```

Obviously you do not need all of this, you can remove the formatting. But this should get you started.

And that's about it really.

Categories Software Development | Tagged asp.net, dialog, javascript, jQuery, popup

CSS Minimum height

CSS Minimum height

I have come to love using a CSS design over ugly, change resistant tables. However the eternal annoyance is getting the design to work correctly with Internet Explorer as well as lovely standards compliant browsers.

One main issue i have is getting a div to have a minimum height specified for all browsers so it doesn't squash up when there is no content. Here is a nice way to do it:

#main {
  height: auto !important; /* IE6 ignores */
  height: 500px; /* IE6 uses this as specified later */
  min-height: 500px;
}

The first line is for Firefox, the middle for IE6 and the last for IE7. Works like a charm :)

Categories Software Development | Tagged css, styling