 |
| Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XsnLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | FileType | xsn | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.2 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.3 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.4 | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsx | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsb | 255 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsx | 256 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsb | 256 |
|
|
| Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XsnLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | FileType | xsn | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.2 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.3 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.4 | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsx | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsb | 255 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsx | 256 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsb | 256 |
|
|
| Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XsnLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | FileType | xsn | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.2 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.3 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.4 | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsx | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsb | 255 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsx | 256 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsb | 256 |
|
|
|
 |
|
|
|
|
|
|
|
6/17/2007
Here's a question I hear a lot: "Should I use a Web Site (WS) or Web Application (WAP) for my ASP.NET 2.0 project?" Certainly Web Site projects look attractive when you are using a free copy of Visual Web Developer and a just have a couple of pages in your site. But how do they work for a real application?
There are many differences between these two project types and the choice will often be made based on either developer preference or operations considerations. Project type usually has no impact on the capabilities or performance of the application itself – except for any compilation you postpone to runtime. But if you are a developer using VS.NET 2005 for a medium-to-large application, WAPs can save you a lot of time over WSs. The full-site compilation tax for Web Site projects is very noticeable, and must be paid every time you:
- Run the site (debug or not)
- Use the refactoring tools
- Run code analysis
I am that VS2005 developer and this is the deal-breaker for me. I just hate how much it slows down my coding. So, for all but the most trivial projects I use a WAP.
But not everyone feels uncomfortable with the compilation tax. Since some folks will choose to use a Web Site project for a productions web app, I'll add this tip: consider compiling and deploying the entire site as a single DLL to avoid the runtime recompilation vulnerability. ScottGu has a number of must-read compilation and deployment tips for Web Site project users.
Here's a checklist of differences between the project types:
| |
Web Site (WS) |
Web Application (WAP) |
Comments |
|
Tools support |
VS.NET, Web Developer, notepad |
Requires VS.NET 2005, SP1 and later |
|
|
Supported page code models |
Code-beside
Code-in-page |
Code-behind
Code-beside
Code-in-page |
All code models work in both models, including the code-in-ASPX model.
Code-behind also generates a partial class for code declarations in a designer.cs file |
|
Time for full site compilation |
Very high |
Normal |
The time to compile a WS scales in an almost linear fashion with the number of pages in the project. For a medium-sized projects, a full-site compile for a WAP can be 10x faster than a full-site compile for a WS.
Full site compilation can have a significant impact on developers that use VS.NET refactoring features. |
|
"Magic" |
Mostly compile-time magic:
Namespaces can be random and generated at compile time
DLL are randomly named at compile time
Assembly references are inferred from #using statement and DLLs in the bin directory |
Mostly design-time magic:
.designer files are generated for control declarations |
Overall, WAPs are much less magical.
Less magic can be helpful for cases where you want to exercise explicit control over how components appear to each other.
Magical assembly references in WSs can be harder to manage for a team project. |
|
Production recompilation vulnerability |
Utilities that touch source files in the production environment (like virus checkers) can cause recompilation, and may cause an app restart as well. |
n/a |
For WS projects, this vulnerability can be mitigated by compiling the entire site to a DLL. |
|
Deploy changes to only part of the web application |
Because the page DLLs are magically named at compilation time, it's often difficult to replace a single page without restarting the application. |
Partial changes can be deployed by copying markup files (if needed) and the site DLL to the production server. |
Contrary to what most folks would guess, the magical compilation of WSs makes it a bit more difficult to deploy partial site changes than for WAPs. |
|
Team-wide code analysis rules supported? |
no |
yes |
Code analysis rules are part of the project for WAPs, and can be standardized and checked in for the whole team. WSs support unshared personal rules only. |
|
Resources |
The WS model splits the majority of string resources in separate, per-page resource files. It's possible to use Global resources, but more clunky. |
Per-page or explicit models supported. |
Per-page file approach can increase the cost of localization (round-tripping multiple files to the translation vendors). |
|
XML documentation support (VS.NET) |
no |
yes |
|
|
Strongly-typed MasterPage support |
no |
yes |
Using strongly-typed MasterPages, you can define members on the MasterPage that are available to all of the derived pages, without resorting to reflection. |
|
Supported by Team System Build? |
no |
yes |
|
|
Project to project references supported |
no |
yes |
For WSs, you must copy the built DLLs into the WS's bin folder, either manually or by doing some fiddling with the build output path in the component project. |
|
Cross-project debugging supported |
sorta |
yes |
With project to project references (WAP), you can debug into a component project in the solution with no additional setup. It just works. For WSs you must build a debug version of the component and manually attach to it during your debug session. | 6/7/2007I'm working on a little WPF application and I need to add an icon that plays well on Vista. There's great prescriptive guidance on MSDN here – well worth a read!
One of the tools the article recommends is IconWorkshop from Axialis (say that 5 times fast). It's a pretty amazing tool. I'm no genius with graphics or graphics tools, and IconWorkshop would have to be amazing indeed to fix that. But it does have nice support for 256x256 RBG/A 32-bit icons, including an option to save them in a compressed format supported by Vista.
Best of all is the "Add Several Image Formats from This Image…" option. I created my 256x256 image first, then generated a 48x48 image which I edited to remove the countdown numbers. Then I generated all the other formats from the 48x48 image. The total size of the resulting .ICO file: 50 KB.

5/30/2007
In my previous post I discussed Drag/Drop in WPF. Often drag/drop is a user gesture to exchange data between two applications, or between parts of an application. But sometimes dragging alone is used as a gesture to scroll some content that's too big to see all at once. Most online map sites let you drag the map image to reveal a different part of the map – in effect, scrolling it.
In the Family.Show reference app, Ralph Arvesen enabled the drag-to-scroll gesture to position the family genealogy graph using the ScrollViewer control and mouse events. It's a nifty approach that I've extracted out into a bare bones example.
The WPF ScrollViewer control already handles positioning content using the scrollbars and clipping of content within its viewport. All that's left is for your code to do is to handle the mouse events and position the content programmatically. Mouse events are implemented in WPF as attached events, and to make things even easier UIElement exposes an alias event for each mouse event. This sample just overrides the event handler methods on Page, which derives from UIElement.
The ScrollViewer's extent is sized to hold the content (in this example, an explicitly-sized Canvas), and the Scrollviewer's viewport is sized to fit within a window, page or some other XAML content control. When the viewport is smaller than the content, the drag-to-scroll behavior is enabled.
On PreviewMouseDown, the original scroll position of the content within the viewport is noted. Each time PreviewMouseMove fires the scroll position is updated, giving the user constant feedback.
XAML
<Page x:Class="WindowsApplication1.Page1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <ScrollViewer x:Name="myScrollViewer" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" > <Canvas Height="2000" Width="3000"> <Label x:Name="myLabel">Here's my label.</Label> </Canvas> </ScrollViewer> </Page>
Code
public partial class Page1 : System.Windows.Controls.Page { private Point mouseDragStartPoint; private Point scrollStartOffset;
public Page1() { InitializeComponent(); myLabel.Loaded += new RoutedEventHandler(myLabel_Loaded); }
protected override void OnPreviewLeftMouseDown(MouseButtonEventArgs e) { mouseDragStartPoint = e.GetPosition(this); scrollStartOffset.X = myScrollViewer.HorizontalOffset; scrollStartOffset.Y = myScrollViewer.VerticalOffset;
// Update the cursor if scrolling is possible this.Cursor = (myScrollViewer.ExtentWidth > myScrollViewer.ViewportWidth) || (myScrollViewer.ExtentHeight > myScrollViewer.ViewportHeight) ? Cursors.ScrollAll : Cursors.Arrow;
this.CaptureMouse(); base.OnPreviewMouseDown(e); }
protected override void OnPreviewMouseMove(MouseEventArgs e) { if (this.IsMouseCaptured) { // Get the new mouse position. Point mouseDragCurrentPoint = e.GetPosition(this);
// Determine the new amount to scroll. Point delta = new Point( (mouseDragCurrentPoint.X > this.mouseDragStartPoint.X) ? -(mouseDragCurrentPoint.X - this.mouseDragStartPoint.X) : (this.mouseDragStartPoint.X - mouseDragCurrentPoint.X), (mouseDragCurrentPoint.Y > this.mouseDragStartPoint.Y) ? -(mouseDragCurrentPoint.Y - this.mouseDragStartPoint.Y) : (this.mouseDragStartPoint.Y - mouseDragCurrentPoint.Y));
// Scroll to the new position. myScrollViewer.ScrollToHorizontalOffset(this.scrollStartOffset.X + delta.X); myScrollViewer.ScrollToVerticalOffset(this.scrollStartOffset.Y + delta.Y); } base.OnPreviewMouseMove(e); }
protected override void OnPreviewMouseUp(MouseButtonEventArgs e) { if (this.IsMouseCaptured) { this.Cursor = Cursors.Arrow; this.ReleaseMouseCapture(); } base.OnPreviewMouseUp(e); }
void myLabel_Loaded(object sender, RoutedEventArgs e) { //center the label initially myLabel.SetValue(Canvas.LeftProperty, ((myScrollViewer.ExtentWidth / 2) - (myLabel.ActualWidth / 2))); myLabel.SetValue(Canvas.TopProperty, ((myScrollViewer.ExtentHeight / 2) - (myLabel.ActualHeight / 2))); myScrollViewer.ScrollToHorizontalOffset( (myScrollViewer.ExtentWidth / 2) - (myScrollViewer.ViewportWidth / 2)); myScrollViewer.ScrollToVerticalOffset( (myScrollViewer.ExtentHeight / 2) - (myScrollViewer.ViewportHeight / 2)); } }
Enjoy ~ Susan
Recently I had my first opportunity to add drag/drop functionality to a WPF application and I learned that WPF doesn't change the recipe for drag/drop much from previous Windows client technologies. It's not too surprising, really, since most of us will want our WPF applications to "play nice" with Windows and other applications your user is running. And mostly, that means sharing data in a standard way between applications.
The data exchange mechanism between the "drag source" application and the "drop target" application is an object that implements IDataObject. (The drag source and drop target can be the same application, of course.) In WPF the IDataObject is passed from the drag source by the System.Windows.DragDrop.DoDragDrop() method, and received by the drop target as the Data member of DragEventArgs. The IDataObject also provides some methods for inspecting what data is available and which UX gesture was should be applied to the data (copy, move, etc.).
In WPF, as with earlier technologies, you'll encounter the "three bears" of drag/drop implementation complexity. Here are some simple examples that illustrate the differences.
Baby Bear: Your app is a drop target for another app's drag data
The simplest drag/drop implementation only has to read the data passed by another application (or Windows) when a user drops and object on your application. This example lets a user drag a file from the desktop and drop it on a StackPanel in your application. The creation of the IDataObject is the job of the drag source, so Windows has already taken care of that part for you. Your app just handles the WPF Drop event and queries e.Data for the file that was dragged.
XAML
<Page x:Class="SimpleDropTarget" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <StackPanel AllowDrop="True" Drop="FileDropHandler"> <Label x:Name="myLabel" >Drop a file here</Label> </StackPanel> </Page>
Code
public partial class SimpleDropTarget : System.Windows.Controls.Page { + default constructor
private void FileDropHandler(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { //Do work. Can special-case logic based on Copy, Move, etc. string[] fileNames = e.Data.GetData(DataFormats.FileDrop, true) as string[]; myLabel.Content = fileNames[0] as string; }
e.Handled = true; } }
Mama Bear: Your application is a drag source
When your application wants to act as the source of some dragged data, things start to get a bit more involved. Now, you must handle mouse events to detect when dragging is happening and figure out what UIElement is being dragged. And your code must create an IDataObject with the data you'd like to pass to the drop target.
Note that when your application is both the drag source on the drop target it's often useful to pass data in a custom format that you define, rather than using one of the canned ones defined by the DataFormats object.
Here's a bare-bones code example that passes a file name:
XAML
<Page x:Class="WindowsApplication1.SimpleDragSource" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > <Canvas> <ListBox x:Name ="fileList" PreviewMouseDown="ListBoxItemDragBegin" PreviewMouseMove="ListBoxItemDragMove" /> </Canvas> </Page>
Code
public partial class SimpleDragSource : System.Windows.Controls.Page { bool dragStarted;
public SimpleDragSource() { InitializeComponent();
//bind a list of files to the ListBox DirectoryInfo windowsDir = new DirectoryInfo("c:\\windows"); fileList.ItemsSource = windowsDir.GetFiles(); }
private void ListBoxItemDragBegin(object sender, MouseButtonEventArgs e) { dragStarted = true; base.OnPreviewMouseDown(e); }
private void ListBoxItemDragMove(object sender, MouseEventArgs e) { if (dragStarted && sender is ListBox) { //create data object ListBox theList = sender as ListBox; DataObject data = CreateDataObjectFromList(theList);
//trap mouse events for the list, and perform drag/drop Mouse.Capture(sender as UIElement); System.Windows.DragDrop.DoDragDrop(theList, data, DragDropEffects.Copy); Mouse.Capture(null);
dragStarted = false; base.OnPreviewMouseMove(e); } }
private DataObject CreateDataObjectFromList(ListBox list) { DataObject data = new DataObject(); FileSystemInfo current = list.SelectedItem as FileSystemInfo; if (current != null) data.SetData(DataFormats.FileDrop, new string[] { current.FullName as string }); return data; } }
Papa Bear: Full Blown Drag/Drop
The examples above are instructive, but the approaches they show are effective for only the most basic drag/drop scenarios. For applications that make more extensive use of drag/drop you'll want to consider:
- Refactoring the event handling and DataObject creation logic so it can be used for multiple drag sources and drop targets in your application. Otherwise, you'll find yourself writing a lot of redundant code.
- Adding user feedback for dragging. At a minimum change the cursor to something that indicates "drag in progress" or – since this is WPF and it's easy to do spiffy visualizations – show a preview of the item to be dropped under the cursor.
Pavan Podila's library tackles both of these requirements in a nice, reuseable way. Lester Lobo cleaned it up a little and shares his version here.
Enjoy ~ Susan 3/21/2007For quite a while now (like, 20 years) I've been sending new emails every day. And never, until Outlook 2007, have I had emails indent each new paragraph by default. Perhaps it's more correct than having flush-left paragraphs, but it just feels wrong to me.
But getting rid of the indent was trickier than I would have guessed. Changing this meant changing the new email template (that part I guessed), specifically I had to change the template's styles. (Simply changing the formatting of the template's first paragraph didn't do the trick.) Here are the steps:
- Close Outlook.
- Edit the new email template using Word 2007: C:\Documents and Settings\user name\Application Data\Microsoft\Templates\NormalEmail.dotm. (Your path may vary, but this is the default.)
- Right-click the Normal style in the Styles group, and Modify.
- Make your changes to Normal as desired. In my case, I changed the Paragraph settings to remove the indent.
- Save your changes, and close Word.
- Re-open Outlook.
Now new messages will be formatted with your changes. 2/2/2007I'm just a code monkey, so there's a truckload of stuff about image formats I've never bothered to try to understand… bit depths, palettes, embedded profiles. If you want to see my eyes lose focus and my mouth go slack, just start talking about chroma subsampling.
Thankfully, Vertigo has an excellent team of designers to shield me from such stuff most days. During yesterday's 10th anniversary festivities I found myself on my own trying to compress some images as JPEGs. I learned a trick for getting smaller, good looking images for a web site– without have to really understand what's going on:
- Use Photoshop's (or Photoshop Elements) "Save for Web" feature
For each quality setting I used (I ended up going with the "JPEG High" preset) the size of the resulting image was significantly smaller than images created using "Save As JPEG" in Photoshop or Paint Shop Pro – 7k vs. 24k for one of the images on our People page. But the quality was identical.
So why would that be? I'm no expert but some explanations suggest it's likely due to simply removing the extraneous information from the file, like EXIF data, embedded profiles and the like. Save for Web apparently also converts the image to 8-bit depth, sRBG as well.
| Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XsnLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | FileType | xsn | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.2 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.3 | 255 | | Edit in Browser | /_layouts/images/icxddoc.gif | /personal/swarren/Blog/_layouts/formserver.aspx?XmlLocation={ItemUrl}&OpenIn=Browser | 0x0 | 0x1 | ProgId | InfoPath.Document.4 | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsx | 255 | | View in Web Browser | /_layouts/images/ichtmxls.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&DefaultItemOpen=1 | 0x0 | 0x1 | FileType | xlsb | 255 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsx | 256 | | Snapshot in Excel | /_layouts/images/ewr134.gif | /personal/swarren/Blog/_layouts/xlviewer.aspx?listguid={ListId}&itemid={ItemId}&Snapshot=1 | 0x0 | 0x1 | FileType | xlsb | 256 |
|
|
|
|
|
|
|
|