This is somewhat based on Shawn Wildermuth’s blog post for drag and drop. I had two problems with his post.
- I’m not scrolling a canvas.
- If your mouse leaves the control with the button down you are still dragging when your mouse reenters the control.
So here’s my tweaked version:
The control has a scroll viewer as the root element and a simple grid with one column and one row inside that. There is a large image inside the grid cell. There are events firing from the grid’s mouse down, up, move and grid leave events.
<UserControl x:Class="TestMouseScroll.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="300" Height="300" Background="Transparent" >
<ScrollViewer
x:Name="scrollViewImage"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible" >
<Grid
x:Name="gridImageContainer"
Background="Gray"
ShowGridLines="True"
MouseLeftButtonDown="grid_MouseLeftButtonDown"
MouseLeftButtonUp="grid_MouseLeftButtonUp"
MouseMove="grid_MouseMove"
MouseLeave="grid_MouseLeave"
>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Image Source=http://www.inetres.com/gp/military/infantry/rifle/M107/M107_1.jpg
Grid.Row="0" Grid.Column="0" >
</Image>
</Grid>
</ScrollViewer>
</UserControl>
The code looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace TestMouseScroll
{
public partial class Page : UserControl
{
bool isTracked = false;
Point startDrag;
public Page()
{
InitializeComponent();
}
private void grid_MouseLeftButtonDown(object sender,
MouseButtonEventArgs e)
{
isTracked = true;
// Get the starting mouseposition based on
// where the mouse is positioned on the image,
// not the relative postion inside the scroller
startDrag = e.GetPosition(gridImageContainer);
}
private void grid_MouseLeftButtonUp(object sender,
MouseButtonEventArgs e)
{
isTracked = false;
}
private void grid_MouseLeave(object sender, MouseEventArgs e)
{
isTracked = false;
}
private void grid_MouseMove(object sender, MouseEventArgs e)
{
if (isTracked)
{
Point newPos = e.GetPosition(scrollViewImage);
try
{
scrollViewImage.ScrollToHorizontalOffset(startDrag.X - newPos.X);
scrollViewImage.ScrollToVerticalOffset(startDrag.Y - newPos.Y);
}
catch { }
}
}
}
}
I think this is pretty straight forward and works nicely for me.
Incidentally, the Barrett was a sniper rifle introduced into the T/E of my unit some time between ‘91 and ‘93. I don’t know exactly when but it wasn’t there the first time I deployed and it was the second time. Used primarily as a vehicular countermeasure, it is still in use today. It’s an awesome addition to any infantry or STA unit firing accurately in the multi-kilometer range (v/s ~1,000 meters for standard 7.62). Note that the kevlar helmet has a USMC Corporal’s rank insignia on it. That’s E4. So a 21 year old professional warrior is trained and deployed with this little monster. Happens every day. There are people who have served in Congress and the House for many decades who cannot be trusted with a spitwad in a McDonalds straw but they have the power to send these fine gentlemen into harms way to voluntarily perform honorably and under stresses and conditions that would make normal men soil themselves. My point is that there ought to be a qualification process to be allowed to make our laws similar to the qualification it takes to become a Marine Sniper. An old Marine can wish…
I got this last night while trying to load 2,150 images into a grid. I’m working on a map tiling control for my application because the maps are very large and custom stitched for my application. Incidentally, when loaded up, my IE windows consumes 1.3 Gb of Ram. Um, probably not gonna work in production…
Anyway, it appears that there is a mechanism internal to the System.Windows.Media.Imaging.BitmapImage object that, when instanced using a Uri, will go in search of the thumbs.db object. I have not looked into the source code for this library and I have not tested to see if this is also happening when on the internet but it doesn’t really matter because it is an easy solution.
To resolve the issue I just opened the images folder in IE and viewed it in thumbnail mode. This magically generates the thumbs.db file and the error goes away when I run my application again.
Incidentally, Xaml1 is the auto-generated name of the <asp:Silverlight /> control that is dropped into the test aspx page.
GPX is the standardized file format for GPS file exchanges. A GPX file can contain a lot of different kinds of information. Take a look at the schema here. In general, the major things that you will work with are:
Waypoints
A waypoint is a specific position that is manually marked by a user for future reference. So when you get to the suspension bridge, mark a waypoint and you can find it again later as well as tell everyone else about it.
Tracks
Tracks are where you've been. When I want to mark out a trail for users of my application, I set up my GPS on my bike and just go for a ride. GPS antennae have come a long way in the last few years and my inexpensive Garmin eTrex keeps pretty accurate markers even when I'm in a deep draw. When I get home I have a complete listing of a few hundred points on my route, depending on how far apart or how long to wait I've preset my GPS to mark between saved track points.
Routes
A route is what you load into your GPS. It's essentially a list of positions you build by looking at a map or a file you get from someone else's track. When loaded, it will direct you to each point along the route in the appropriate order.
My Garmin saves files in a GDB format which is proprietary for the product. I load this file onto a machine with Garmin MapSource and immediately save the file as a GPX. This gets it into the standardized format that nearly all other GPS units and mapping software can use and I'm ready to load my data. At the end of this post is a well formed (but incomplete) GPX file. The original file had about 6,500 lines in it.
The Code
It's really pretty straight forward once you realize that you need to pull in the namespace object and then include it in each call to an element. My initial run at this netted attribute values but no element values which was really frustrating. Also, when working with Xml, remember that an element that doesn't exist results in a null object reference so you'll see in the code how I handled that for each element. The biggest issue for me with Linq is the inability to debug line-by-line. Still it's crazy fast and I'm loading a lot of data in only a few lines of code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;
namespace LinqXMLTester
{
public class GPXLoader
{
/// <summary>
/// Load the Xml document for parsing
/// </summary>
/// <param name="sFile">Fully qualified file name (local)</param>
/// <returns>XDocument</returns>
private XDocument GetGpxDoc(string sFile)
{
XDocument gpxDoc = XDocument.Load(sFile);
return gpxDoc;
}
/// <summary>
/// Load the namespace for a standard GPX document
/// </summary>
/// <returns></returns>
private XNamespace GetGpxNameSpace()
{
XNamespace gpx = XNamespace.Get("http://www.topografix.com/GPX/1/1");
return gpx;
}
/// <summary>
/// When passed a file, open it and parse all waypoints from it.
/// </summary>
/// <param name="sFile">Fully qualified file name (local)</param>
/// <returns>string containing line delimited waypoints from
/// the file (for test)</returns>
/// <remarks>Normally, this would be used to populate the
/// appropriate object model</remarks>
public string LoadGPXWaypoints(string sFile)
{
XDocument gpxDoc = GetGpxDoc(sFile);
XNamespace gpx = GetGpxNameSpace();
var waypoints = from waypoint in gpxDoc.Descendants(gpx + "wpt")
select new
{
Latitude = waypoint.Attribute("lat").Value,
Longitude = waypoint.Attribute("lon").Value,
Elevation = waypoint.Element(gpx + "ele") != null ?
waypoint.Element(gpx + "ele").Value : null,
Name = waypoint.Element(gpx + "name") != null ?
waypoint.Element(gpx + "name").Value : null,
Dt = waypoint.Element(gpx + "cmt") != null ?
waypoint.Element(gpx + "cmt").Value : null
};
StringBuilder sb = new StringBuilder();
foreach (var wpt in waypoints)
{
// This is where we'd instantiate data
// containers for the information retrieved.
sb.Append(
string.Format("Name:{0} Latitude:{1} Longitude:{2} Elevation:{3} Date:{4}\n",
wpt.Name,wpt.Latitude,wpt.Longitude,
wpt.Elevation, wpt.Dt));
}
return sb.ToString();
}
/// <summary>
/// When passed a file, open it and parse all tracks
/// and track segments from it.
/// </summary>
/// <param name="sFile">Fully qualified file name (local)</param>
/// <returns>string containing line delimited waypoints from the
/// file (for test)</returns>
public string LoadGPXTracks(string sFile)
{
XDocument gpxDoc = GetGpxDoc(sFile);
XNamespace gpx = GetGpxNameSpace();
var tracks = from track in gpxDoc.Descendants(gpx + "trk")
select new
{
Name = track.Element(gpx + "name") != null ?
track.Element(gpx + "name").Value : null,
Segs = (
from trackpoint in track.Descendants(gpx + "trkpt")
select new
{
Latitude = trackpoint.Attribute("lat").Value,
Longitude = trackpoint.Attribute("lon").Value,
Elevation = trackpoint.Element(gpx + "ele") != null ?
trackpoint.Element(gpx + "ele").Value : null,
Time = trackpoint.Element(gpx + "time") != null ?
trackpoint.Element(gpx + "time").Value : null
}
)
};
StringBuilder sb = new StringBuilder();
foreach (var trk in tracks)
{
// Populate track data objects.
foreach (var trkSeg in trk.Segs)
{
// Populate detailed track segments
// in the object model here.
sb.Append(
string.Format("Track:{0} - Latitude:{1} Longitude:{2} " +
"Elevation:{3} Date:{4}\n",
trk.Name, trkSeg.Latitude,
trkSeg.Longitude, trkSeg.Elevation,
trkSeg.Time));
}
}
return sb.ToString();
}
}
}
GPX Sample File
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<gpx xmlns="http://www.topografix.com/GPX/1/1"
creator="MapSource 6.13.7"
version="1.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.garmin.com/xmlschemas/GpxExtensions/v3
http://www.garmin.com/xmlschemas/GpxExtensions/v3/GpxExtensionsv3.xsd
http://www.topografix.com/GPX/1/1
http://www.topografix.com/GPX/1/1/gpx.xsd">
<metadata>
<link href="http://www.garmin.com">
<text>Garmin International</text>
</link>
<time>2009-03-08T20:11:54Z</time>
<bounds
maxlat="39.2971185"
maxlon="-76.6951826"
minlat="39.2035537"
minlon="-76.8203088"/>
</metadata>
<wpt lat="39.2445616" lon="-76.7194497">
<ele>88.8067627</ele>
<name>001</name>
<cmt>16-SEP-08 8:50:11AM</cmt>
<desc>16-SEP-08 8:50:11AM</desc>
<sym>Residence</sym>
<extensions>
<gpxx:WaypointExtension
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3">
<gpxx:DisplayMode>SymbolAndName</gpxx:DisplayMode>
</gpxx:WaypointExtension>
</extensions>
</wpt>
<wpt lat="39.2422711" lon="-76.7213488">
<ele>38.3380127</ele>
<name>009</name>
<cmt>16-SEP-08 9:40:46AM</cmt>
<desc>16-SEP-08 9:40:46AM</desc>
<sym>Residence</sym>
<extensions>
<gpxx:WaypointExtension
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3">
<gpxx:DisplayMode>SymbolAndName</gpxx:DisplayMode>
</gpxx:WaypointExtension>
</extensions>
</wpt>
<trk>
<name>Vinyard Springs Loop</name>
<extensions>
<gpxx:TrackExtension
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3">
<gpxx:DisplayColor>Transparent</gpxx:DisplayColor>
</gpxx:TrackExtension>
</extensions>
<trkseg>
<trkpt lat="39.2446415" lon="-76.7199907">
<ele>60.2197266</ele>
<time>2009-03-08T13:18:25Z</time>
</trkpt>
<trkpt lat="39.2445078" lon="-76.7193838">
<ele>88.0980225</ele>
<time>2009-03-08T13:19:23Z</time>
</trkpt>
<trkpt lat="39.2440145" lon="-76.7200792">
<ele>81.3687744</ele>
<time>2009-03-08T13:19:43Z</time>
</trkpt>
<trkpt lat="39.2435182" lon="-76.7208523">
<ele>82.3300781</ele>
<time>2009-03-08T13:20:04Z</time>
</trkpt>
<trkpt lat="39.2427701" lon="-76.7212304">
<ele>78.9654541</ele>
<time>2009-03-08T13:20:52Z</time>
</trkpt>
<trkpt lat="39.2417241" lon="-76.7208448">
<ele>65.0263672</ele>
<time>2009-03-08T13:21:43Z</time>
</trkpt>
</trkseg>
</trk>
<trk>
<name>Patapsco Boundry Ref</name>
<extensions>
<gpxx:TrackExtension
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3">
<gpxx:DisplayColor>DarkRed</gpxx:DisplayColor>
</gpxx:TrackExtension>
</extensions>
<trkseg>
<trkpt lat="39.2253216" lon="-76.7073387">
<ele>46.2806396</ele>
</trkpt>
<trkpt lat="39.2248415" lon="-76.7065894">
<ele>43.3966064</ele>
</trkpt>
<trkpt lat="39.2194385" lon="-76.7042182">
<ele>17.4411621</ele>
</trkpt>
<trkpt lat="39.2188285" lon="-76.7043919">
<ele>15.0377197</ele>
</trkpt>
<trkpt lat="39.2183665" lon="-76.7051846">
<ele>14.0764160</ele>
</trkpt>
<trkpt lat="39.2180424" lon="-76.7061647">
<ele>12.6343994</ele>
</trkpt>
<trkpt lat="39.2177812" lon="-76.7070982">
<ele>11.1925049</ele>
</trkpt>
<trkpt lat="39.2485097" lon="-76.8098993">
<ele>127.5119629</ele>
</trkpt>
</trkseg>
</trk>
</gpx>
My plan was to take my application into SQL 08 from 05 since my hosting service now has it available. I was intent on killing all of my lat/long information and storing my geospatial data in geography columns.
Here is what I’m finding about the Geography and Geometry data types. Initially, I expected to that once in, I’d be able to get everything back out exactly as entered.
Not so much…
Here is what I am finding so far. When/if I figure each of these out I’ll post an update.
- Geography and Geometry are across a uniform surface. That means no elevation. So if I’m trying to track the distance between points A and B I can only do it as if looking directly down at a map.
- Data cannot be read by humans from geography and geometry types. Put the value in and see what it looks like when you select it back out. Not a big deal but it sucks when you’re trying to QA input procedures that have 600 points on a single track.
- Similar to the previous item, data is for input only. If I put in a geography point, I cannot easily extract just the latitude only from that column. I can do it by parsing and using .ToString() but ugh!
So in my data I’ll be storing the latitude, longitude, elevation and ALSO the geography-coded value for the latitude/longitude.
The upside is that it should make it easier to calculate trip plans for individual users since this is part of my plan to try and pay for that big expensive camera that I’ll be using to snap a zillion panoramas. In the end, what I’ve found is that the geography and geometry data types are primarily useful for making geospatial calculations, not for viewing the actual geospatial data itself.
A substantial part of a developer’s job seems to be the logistical details of getting ‘it’ from here to there. When you run a team the problem becomes larger. Even with source control, there are documents that should be updated that aren’t and things that should be done that are missed. The two tools that I use these days are Beyond Compare from Scooter Software for files and folders and Red Gate’s SQL Compare for databases. The former is dirt cheap, the later has gotten more expensive over the years.
I’ve used Beyond Compare for a number of years now and have always been impressed with the comprehensive but simple nature of the software. You can open the UI for the first time and stumble around for about 5 minutes and know what you’re doing. In addition, the support is truly outstanding. Getting upgrade keys and information about the product reminds me of working with the the auto shop I have been going to for 10 years or more. I walk in and they know me by name even if I haven’t been around for 6 months. They give me exactly the services I need, listen carefully to any concerns I have and refuse to charge me when out of the ordinary things happen. Scooter Software’s licensing model is very straight forward for a single developer: As long as I’m using it personally, I can put it wherever I want. I have it on my personal dev box, my wife’s machine and my company dev box. If I ever get rid of the company box, I’ve got a note-to-self to remove it. Simple model based on trusting your client.
I also use Beyond Compare to keep my local backups up to date. In all the time that I have been taking digital photographs, I think I’ve actually deleted a half dozen. Needless to say I have thousands. Before I set up with carbonite.com, I used a rotating system of 2 external hard drives. I keep one attached to my local machine and one in the fireproof safe. I put all new images on my local internal media drive and then do a compare on the external, moving anything that doesn’t exist over. Then, every week or so, I swap the drives in the safe and do another compare. It takes a minute or two and I know that all the pictures and movies my family has are protected in the safe. My wife’s machine also gets an occasional copy of all images and movies so she can show off when she’s out and about doing FCC related stuff.
I wish I had done that for my Silverlight program. If I had I wouldn’t have lost 3 months of work due to sheer stupidity and a WD drive that went thud…
At any rate, I highly recommend both of these companies and their products.
I’m currently using a relatively well known hosting service for my Silverlight 2 application. The problem that I’ve had in getting the app up and running is that in a shared hosting environment, I have no control over host headers and most of the other settings in IIS. So since my url is https://www.singletrax.com, the ops people also added https://singletrax.com to the host headers for my site.
The problem is the order in which they added them. The www address is the second in the list so when I try to link to my services, I get an exception: Exception has been thrown by the target of an invocation. This is because the service is trying to load the host header index of 0 and there ain’t nuthin’ you can do about it that I’ve been able to find!
Except this:
First, add an AppSetting to your web project:
<appSettings>
<add key="HostIndex" value="1" />
</appSettings>
Next, create two new objects:
using System;
using System.Collections.Generic;
using System.Web;
using System.Configuration;
using System.ServiceModel;
using System.ServiceModel.Activation;
namespace MyNamespace.Web.Objects
{
class CustomHostFactory : ServiceHostFactory
{
protected override ServiceHost
CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
int hostIndex =
Convert.ToInt32(ConfigurationManager.AppSettings
["HostIndex"].ToString());
CustomHost customServiceHost =
new CustomHost(serviceType, baseAddresses[hostIndex]);
return customServiceHost;
}
}
class CustomHost : ServiceHost
{
public CustomHost(Type serviceType,
params Uri[] baseAddresses) : base(serviceType, baseAddresses)
{ }
protected override void ApplyConfiguration()
{
base.ApplyConfiguration();
}
}
}
Then, in your .svc file, reference the custom host this way:
<%@ ServiceHost Language="C#" Debug="true"
Service="MyNamespace.Web.Services.MyService"
CodeBehind="MyService.svc.cs"
Factory="MyNamespace.Web.Objects.CustomHostFactory" %>
This works well for me. I’d be interested in what other hosting services do. Incidentally, I made the index an app setting because I hope that as traffic increases I’ll be able to afford a dedicated or virtual hosting environment.
I’ve got lots of lat/long information for my Silverlight 2 application and I’m now tinkering with getting the elevation view working in my spare time. The problem is that the distances are very small and the haversine formulae I’ve located on the internet are all either miles or kilometers. Not going to work when your next position is only 50 feet away. So I wrote the simple SQL function below based directly on Seth Long’s version here.
Now, since I’m storing positional latitude, longitude and intersection information in my database, it’s simple to just calculate the numbers. The input and output values are of course immutable, so I added the columns to the appropriate table and will update them during the data entry phase of normal operations.
The haversine formula is also known as the ‘great circle formula’ that gives you a distance across the surface of a sphere based on an average curvature value for that sphere. The actual pear shape of the earth is a calculated max diff of only about 20 km so I’m not particularly worried about the error in two points that are literally spitting distance from each other.
By the way, the constant value 20,890,584 is the earth’s average radius in miles (3,956.55) multiplied by 5,280 feet per mile. The wikipedia article on haversine states that the average radius of the earth is 6,367.45 Km and I’m assuming it’s correct. I’m defaulting to feet since my Garmin GPS’ standard output for relative elevation is in feet.
@R is the radius of the earth.
This kind of begs for a discussion of whether it is more appropriate to calculate these values on the client and save the bandwidth or do the work on the server and pass it over. I chose the server because I’m still trying to figure out if I can market this application in the SAAS category. In that light, it seems better to keep as much data instantly available as I can.
Here’s the function:
Create Function [dbo].[fnGetDistance]
(
@Lat1 Float(18),
@Long1 Float(18),
@Lat2 Float(18),
@Long2 Float(18),
@ReturnType VarChar(10)
)
Returns Float(18)
AS
Begin
Declare @R Float(8);
Declare @dLat Float(18);
Declare @dLon Float(18);
Declare @a Float(18);
Declare @c Float(18);
Declare @d Float(18);
Set @R =
Case @ReturnType
When 'Miles' Then 3956.55
When 'Kilometers' Then 6367.45
When 'Feet' Then 20890584
When 'Meters' Then 6367450
Else 20890584 -- Default feet (Garmin rel elev)
End
Set @dLat = Radians(@lat2 - @lat1);
Set @dLon = Radians(@long2 - @long1);
Set @a = Sin(@dLat / 2)
* Sin(@dLat / 2)
+ Cos(Radians(@lat1))
* Cos(Radians(@lat2))
* Sin(@dLon / 2)
* Sin(@dLon / 2);
Set @c = 2 * Asin(Min(Sqrt(@a)));
Set @d = @R * @c;
Return @d;
End
I spent quite a bit of time working SharePoint both in an independent project and bug-fixing other people’s work over the last six or seven months. Once you get the paradigm down, it’s not too bad but not exactly a barrel of laughs either. You spend equal thirds of your time developing, debugging and tinkering with the xml files that make up the belly of the beast. I believe that after some old-school SQL work finishes up I’ll be back in that groove. Yippee… I need to noodle around with those certifications too but that’s another story.
My reason for not blogging recently has been that a new toy caught my eye and I’ve been goofing around with Silverlight 2 for the last few months in pretty much all of my spare time. I’ve spent no less than 30 minutes and sometimes upwards of 2 hours a night tinkering out my new application. This is something that I suppose is possible with flash but I’m not a flash guy so I can’t say for sure. The idea of this hit me a few years ago and I was trying to implement it with ajax with limited results. SL makes it relatively easy.
About 2 months ago the hard drive on my personal machine crashed and fried the controller. It might have been the other way around but I ended up losing a load o’ code and had to start from scratch with the original images and the requirements docs I had emailed to myself. Now I’ve got carbonite.
So the application is free for now and I’m going to replace all images with updates from my spankin’ new DSLR. The buttons need templates, the colors of the controls stink and the images take far too long too long to load. That said I think it’s a pretty rich experience. Check it out if you have SL2 installed.
https://www.singletrax.com
I’d be interested in any input from the peanut gallery…
So in a recent SharePoint implementation, I was required to allow users to create links in web parts that performed server side functions. Most of the functions were known quantities but they were almost all external systems. Most of the requirements were to just display security trimmed links to Oracle and other external systems. I had envisioned a single sign-on, BDC system but it turned out the client didn't have the infrastructure to support getting the external data in that way.
My solution was to create an Xml file describing the kinds and order of calls for each web part and place all the Xml files in a document library for extraction and processing. That allows future users to pull the file, edit it and replace it as appropriate. I had a single web part with a custom text property set to the name of the Xml file. So the user added this generic web part to as many pages as necessary and set the property to the flavor they wanted to show on that page in that position. Pretty simple.
So I needed to open a file in memory from a document library and operate on it as a normal Xml document. Here is the basic structure of one of the files. There are a lot more options in the structure but this gives you the idea.
XML
Easy to read and easy to parse. I'm no whiz at parsing Xml but I built a data object to wrap this structure and it seemed to perform pretty well. Here is the code I used to get the Xml file from the library into an Xml document object. This project required VS 2005 so I had no option for using Linq to get the data. Season to taste. Caveat Emptor.
C#

I've seen another way of doing this but this worked best for my situation. I'd be interested in any pointers from others who have a different tack.
JJ
So in the farm I'm trying to deploy to, the tracing service starting logging some "failed to write template" messages. Thousands of them. Nobody was on the machine at the time. It wasn't available to anyone so it was internal to SharePoint, whatever it was. Then it suddenly turned into the "Tracing Service lost trace events" log entries. Finally, it stopped logging altogether.
I found in a forum post on MSDN that when this happens, you need to restart the Windows SharePoint Service Tracing service.
SharePoint immediately started logging the events appropriately.
I love SharePoint and I also hate it.
More Posts
« Previous page -
Next page »