Friday, October 14, 2005

Icons on an Office CommandBar

I've recently had a problem with loading images in Office CommandBar buttons. I found some information on the web about it, but it was neither complete or it , but I took that information further anyways.

First of all, I created a subclass called ImageHost which inherits from AxHost


private class ImageHost : System.Windows.Forms.AxHost
{
public ImageHost() : base("59EE46BA-677D-4d20-BF10-8D8067CB8B33")
{ }

/// <summary>
/// Gets a <see cref="stdole.IPictureDisp">from an input
/// <see cref="System.Drawing.Image">.
/// <summary>
public stdole.IPictureDisp GetIPictureDisp(System.Drawing.Image image)
{
return (stdole.IPictureDisp)GetIPictureDispFromPicture(image);
}

/// <summary>
/// Gets a <see cref="stdole.IPictureDisp"> from an input
/// <see cref="System.Drawing.Icon">.
/// </summary>
/// <remarks>
/// The benefit of this is when you put Icons in the Resources.resx file.
/// It's easy to just drop them in.
/// </remarks>
public stdole.IPictureDisp GetIPictureDisp(Icon icon)
{
System.IO.Stream img = new System.IO.MemoryStream();
icon.Save(img);
return GetIPictureDisp(Image.FromStream(img));
}
}


After setting this up, you must use the image host to get the stdole.IPictureDisp:


CommandBarButton button = CreateButton(
bar, "My Button",
Office.MsoButtonStyle.msoButtonIconAndCaption);
button.Picture = iconHost.GetIPictureDisp(
Properties.Resources.MyButton);


Enjoy!

Wednesday, August 17, 2005

Cross-browser script for LinkList Collections

I really wanted to have the ability to make collections in JavaScript:

function LinkedItem() {
this.Item = null;
this.NextItem = null;
}
function Collection() {
var _root = new LinkedItem();
var _currentItem = _root;
var _resetEnumerator = true;
var INDEX_OUT_OF_RANGE = "Index out of range.";

this.Current = function() {
return _currentItem.Item;
};
this.Add = function (item) {
if (_currentItem.Item == null)
_currentItem.Item = item;
else {
while (this.MoveNext()) {}
_currentItem.NextItem = new LinkedItem();
_currentItem = _currentItem.NextItem;
_currentItem.Item = item;
}
};
this.Remove = function (item) {
var index = this.IndexOf(item);

};
this.RemoveAt = function (index) {
if (index <>= this.Count())
throw new Error(INDEX_OUT_OF_RANGE);

var itmBefore = this.ItemAt(index-1);
var itmMiddle = _currentItem.NextItem;
var itmAfter = itmMiddle.NextItem;

itmBefore.NextItem = (itmAfter != null) ? itmAfter : null;
};
this.IndexOf = function (item) {
counter = -1;
while(this.MoveNext()) {
counter++;
if (this.Compare(item, _currentItem.Item)) {
_resetEnumerator = true;
return counter;
}
}
return -1;
};
this.Compare = function (item1, item2) {
return (item1 == item2) ? 1 : 0;
};
this.MoveNext = function()
{
if (_resetEnumerator) {
_currentItem = _root;
_resetEnumerator = false;
return true;
}
if (_currentItem.NextItem instanceof LinkedItem) {
_currentItem = _currentItem.NextItem;
return true;
} else {
_resetEnumerator = true;
return false;
}
}
this.Loop = function() {
if (_resetEnumerator) {
_currentItem = _root;
_resetEnumerator = false;
return true;
}
if (_currentItem.NextItem instanceof LinkedItem)
_currentItem = _currentItem.NextItem;
else {
_currentItem = _root;
}
return true;
};
this.ItemAt = function (index) {
if (index >= this.Count())
throw new Error(INDEX_OUT_OF_RANGE);
counter = 0;
while (this.MoveNext()) {
if (counter++ == index) {
_resetEnumerator = true;
break;
}
}
return _currentItem;
};
this.Count = function() {
counter = 0;
while (this.MoveNext()) counter++;
return counter;
};
}

Friday, August 05, 2005

Been away for a while...

I haven't had time to write any blog entries since the project I'm working is all NDA. Unfortunately, the project is written all in C which isn't the best for a .NET geek who loves his C's sharpened. There's always that project you wish you didn't have to do... This is that project that no .NET programmer would ever want.

Sunday, July 24, 2005

Pittsburgh .NET User's Group Summer Slam

Went to the Pittsburgh .NET User's Group SummerSlam party on Wednesday night and had a blast. Guys from the CEI office and Microsoft were there including John McClelland and Stan Spotts.

Too bad we couldn't get Matt Trevors and Geoff Tewksbury didn't show up...

Tuesday, June 28, 2005

Finished the MCAD.NET

I passed my 70-320 Web Services exam and achieved my MCAD today! It's my goal to take the security and solutions framework over the next few weeks and finish the MCSD

Friday, June 24, 2005

Winforms exam down! 3 to go!!!

I passed my WinForms MCSD exam today! Woo hoo!!! 3 more exams to go to complete my MCSD.

Thursday, June 16, 2005

SQL Server 2005 Training

I went to Columbus, OH to learn what I don't already know about SQL Server 2005 last week. I was really excited to go because I wanted to see some real examples of using the SQL Service broker and experiment with a mentor doing CLR and XML stuff in SQL. Unfortunately, the hands-on training was just having a laptop and a book that told me exactly what to type in and monitor the result--of which I grew quickly weary.

The training would have been better if it didn't say it was hands on, because I thought I'd get to do a bit of problem solving. I also didn't feel like there was a real explanation of where one could use SQL Service broker other than using the SqlDependency object. Now I can think of a few others, but I didn't learn enough to gauge whether my thought process is correct.

Saturday, June 11, 2005

Finishing Commerce Server site

I'm finishing up another Commerce Server site this week. I had the worst DTC issues because the client is using a firewall that isn't allowing Commerce Server's DCOM components to create transactions. So a call to Basket.SaveAsOrder caused the application to fail.

Finally, I decided to rewrite the base functionality of the SaveAsOrder function storing the order in the Order* tables using only SQL transactions. In doing so, I am sure to lose some functionality with the OrderGroup object in the future, but at least I'll have the order stored in Commerce Server.

Oh well, it's going to be over soon.

Tuesday, May 31, 2005

NTeam

Today, I joined the NTeam project where I'll be working with a friend of mine, Ron Buckton on a competitive open source system. Seems like a lot of fun, but we're still in the planning phase. I say "we" as though I've been working with these guys for a while, and yet I just signed on today.

Monday, May 30, 2005

VS.NET 2005 Team System Training

I got to go to a VS.NET Team System Training seminar on Friday. It was pretty cool, but you could definitely tell it was still beta. I've been playing with 2.0 framework and Whidbey for almost 8 months now and been following it since the whitepapers, so I've been close to the development side, but I haven't really paid much attention to the Team Foundation Server.

Anyways, it was fun to play with the new features of Team System. Microsoft has done a great job creating an extensible interface and yet maintaining such a tight integration with all its other tools (Sql Reporting Services, Microsoft Office, Microsoft Project). The best part is the Enterprise Souce Code Management. Finally, a real source control system that isn't open source and is reliable and fast. YEA!

Thursday, May 19, 2005

If people only knew the power of the UserControl...

It's come to my attention that a lot of people don't understand the power of ASP.NET databinding and using server and user controls efficiently. So I've put together a few tips on making better use of these two demons.
1. User controls are controls. You can create properties in them, and as long as they are public, they are accessible to the parent control in the ASPX page. This gives you the ability to easily databind the control in the ASPX page. A simple example is when you want to display a product. The two easiest ways to handle this situation are to (1) pass the DataRowVersion or Product class directly to the user control, and have the user control bind the data, or (2) pass each property to the user control.
Example user control:
public class Product : UserControl
{
private
DataRowVersion _productData = null;
public Product() {}
public DataRowVersion ProductData
{
// notice, I do not use viewstate to persist this
// information since it is probably persisted
// in the parent control
get { return _product; }
}
...
void BindData() { // handle binding the data }
}
implementing this in a page with a repeater might look like this:
<%@ Register TagPrefix="uc" TagName="Product" Src="~/Product.ascx" %>
<asp:repeater runat="server">
<itemtemplate>
<uc:product runat="server" productdata="'<%# Container.DataItem %>' />
</itemtemplate>
</asp:Repeater>

An example for (2) is very similar and will provide little benefit in demonstration.
Now, what if you want to do some sort of skinning on a user control? Here's a simple method to give your user controls a heading:
This code will give you the ability to skin the heading of your user control and allow you to place content within the user control on the ASPX page
[ParseChildren(true, "WebPartContent")]
public class WebPart : UserControl
{
protected Label WebPartTitle;
protected PlaceHolder WebPartContentPlaceholder;
[Browsable(false)]
public PlaceHolder WebPartContent
{
get { return WebPartContentPlaceholder; }
set { WebPartContentPlaceholder = value; }
}
[Browsable(true)]
public string Title
{
get { return WebPartTitle.Text; }
set { WebPartTitle.Text = value; }
}
}

The ASCX control can look like this:
<table cellpadding="3" cellspacing="0">
<tr>
<!-- Heading -->
<td><asp:Label runat="server" id="WebPartTitle" /></td>
<td width="60" align="right"><asp:Button runat="server" id="CloseButton" /></td>
</tr>
<tr>
<td colspan="2">
<asp:Placeholder runat="server" id="WebPartContentPlaceholder" />
</td>
</tr>
</table>

And the ASPX page can look like this:
<body>
<uc:WebPart runat="server" Title="Web part title">
This is where my user control content will go...
</uc:WebPart>
</body>

Well, I hope you enjoy these. I'll try to demonstrate some other cool techniques in future blogs.

Monday, May 16, 2005

Working on extensible inventory system

I started working on an extensible inventory tracking system this weekend. It will integrate with my already existent content management system and my upcoming extensible shopping cart system.

The idea is to build an application that has plug points for additional functionality that can be easily implemented. The complexity in this is that I want there to be an infinite number of plug points that maintain the ability to interact with each other and allow the minimum number of dependencies...

...and, I hope to do it without going pattern happy.

Monday, May 02, 2005

Neural networks

Figured I'd post a link to something cool. Here's an article that showed up in MSDN mag last month on writing a simple neural network which I would have figured would be written in either C++ or C#--it was written in VB.

http://msdn.microsoft.com/msdnmag/issues/05/05/NeuralNetworks

Monday, March 14, 2005

First day at CEI

Well, I started working at CEI, today. I'm excited because I've already been thrown into the fire of a Commerce Server project. Seems like I will even get to implement some extensions of the new Enterprise Library (probably just logging and data), but it will be fun to get one under my belt.

Friday, March 04, 2005

NetSig Controls available

I never got around to posting that the controls and tools Ron Buckton and I presented in the Feb. Cleveland .NET SIG are all availble for download at:

http://www.bennettadelson.com/technicalresources/presentations.aspx
The title was ASP.NET 2.0 I Want it Now!!!

To see the controls in action, you can toy with them at my site here:
http://www.aspnetgeek.com/NetSig_2-8-05/

There is one bug that you will see when running the web. Please remove the Register directive on the MasterPage.ascx file for the ~/UserControls/Header.ascx.

Thursday, March 03, 2005

MCMS Resource image handler

I’ve been working on rendering resources from MCMS using an HttpHandler. Now I’ve written a class to handle image scaling and quality, and I’ve used this concept in large scale applications; however, I cannot seem to render resources from the Resource Gallery of MCMS consistently.
public void ProcessRequest(HttpContext context)
{
try
{
// get the resource
Resource resource =
(Resource)CmsHttpContext.Current.Searches.GetByGuid(ResourceGuid);

if (resource != null)
{
HttpCachePolicy policy = context.Response.Cache;

policy.SetLastModified(resource.LastModifiedDate);
policy.VaryByParams["w;h;r"] = true;

Stream stream = resource.OpenReadStream();

// Resize the image
ImageResizer.ResizeImage(
stream,
context.Response.OutputStream,
Width,
Height,
true);
}
else
{
context.Trace.Warn(
"No Image",
"Cannot retrieve resource: "
+ ResourceGuid);
RenderNoImage(context);
}
}
catch (Exception ex)
{
context.Trace.Write(ex.ToString());
Controller.Errors.LogError(ex);
RenderNoImage(context);
}
}

I can get this handler to render effectively for the first few requests. After a few requests, the handler consistently fails to retrieve the Resource and the Searches object may even be null.

Tuesday, March 01, 2005

Leaving Bennett Adelson

After a year at Bennett Adelson, I have decided to leave for a Pittsburgh-based company called CEI. There I will be working under Microsoft Regional Director Mike Snell as a .NET Architect.
I am really excited about this venture and I am sure this is a great career move.

Wednesday, February 09, 2005

SIG Presentation

Ron and I had fun giving our presentation last night in Cleveland. We were both writing code up to the last minute for our ASP.NET 2.0 presentation materials, but our ASP.NET 1.1 stuff went over much better.
We're going to cleanup a few things that went awry during the presentation and try to get the code on the Bennett Adelson presentations web site soon.

Monday, February 07, 2005

Microsoft .NET SIG Presentation in Cleveland

Well, we're down to less than 24 hours before my presentation in Cleveland. It's chocked full of good stuff.
Ron Buckton and I are going to be presenting


ASP.NET 2.0: I want it NOW!!!
Duplicating controls and concepts in the 1.1 framework

We're going to be tackling some great concepts:

  • Basic overview of the Provider model
  • Membership (Login controls, Profile, and User listing)
  • Client Callback
  • Master pages
  • Validation groups
  • Resource class and Settings class generators, and
  • Theming

If you want to download the code after Feb. 8th, you'll be able to download it here:
http://www.bennettadelson.com/technicalresources/presentations.aspx