7 posts tagged “c#”
Overview
Silverlight 2 Beta brings the wonders of Silverlight and removes the annoyance of Javascript. The question remains: How do I get Silverlight deployed on my webserver even though it isn't out yet? This article will walk through creating a simple "hello world" silverlight application and deploying it on your webserver. This article assumes you have Silverlight 2 installed with the Visual Studio 2008 templates.
Create the Silverlight project
- Open Visual Studio 2008
- Click File->New Project
- Under Visual C# click Silverlight
- Select Silverlight Application, name it what you want, and click ok
- When it asks you if you would like to create a web project, click add a new and click ok
Now you should have two projects. Under the library, click and open up your Page.xaml file. You are going to add xaml to the Grid control so that it looks like this:
<UserControl x:Class="SilverlightDeploy.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300">
<Grid x:Name="LayoutRoot" Background="White">
<Button x:Name="BtnHelloWorld" Content="Hello World"
Width="100" Height="50" Click="BtnHelloWorld_Click" />
</Grid>
</UserControl>
Then in the Page.xaml.cs file, you need to add the code for the button's Click event:
Now you can build the application, but it is not quite publish ready.
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
}
private void BtnHelloWorld_Click(object sender,
RoutedEventArgs e)
{
this.BtnHelloWorld.Content = "You Clicked Me!";
}
}
Publishing the application
First thing we need to do is create a publish version of the application.
- Right click on the web application and click "Publish Website"
- Specify your publish location (I used the desktop), and click ok
Now the issue with publishing Silverlight 2 is that webservers don't recognize the xap file as a proper mime type. The good thing is xap files are essentially just zip files. With this in mind, we can use some wizard trickery to make it all work happily.
- Go to the folder where you published your web application
- There should be a .xap file in your ClientBin directory. Change the file extension file to .zip instead of .xap
- Go to any pages that reference this file (Visual Studio will have created a [ProjectName]TestPage.aspx and .html file.
- Open the SilverlightDeployTestPage.html and find the object section.
- Rename the .xap reference to .zip as done in the ClientBin file
<object data="data:application/x-silverlight,"
type="application/x-silverlight-2-b1"
width="100%" height="100%">
<param name="source" value="ClientBin/SilverlightDeploy.zip"/>
<param name="onerror" value="onSilverlightError" />
<param name="background" value="white" />
<a href="http://go.microsoft.com/fwlink/?LinkID=108182"
style="text-decoration: none;">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181"
alt="Get Microsoft Silverlight"
style="border-style: none"/>
</a>
</object>
You should be good to go. You can now ftp the site wherever your heart desires and it will work. For now, you have to do this for all of the references to your xap files. I'll keep you posted (No pun intended).
Overview
This is the first of a couple articles on managing web parts. I would like to keep these articles as simple and concise as possible. This tutorial simply covers how to place WebParts onto the screen. WebParts are a portion of Asp.Net that doesn’t receive very much love. From my experience they feel complex, and where to apply them in your application very ambiguous. Let’s just start with creating one.
Creating your WebPart
- Open Visual Studio (I am using 2008), and add a new website
- This will create the Default.aspx page. Open the Default.aspx page
- Create three Divs
- Drag a WebPartManager and a DropDownList in the first
- Drag a WebPartZone in the second
- Drag a WebPartZone in the third
<div>
<asp:WebPartManager ID="WebPartManager1" runat="server">
</asp:WebPartManager>
<asp:DropDownList ID="DropDownList1" runat="server">
</asp:DropDownList>
</div>
<div>
<asp:WebPartZone ID="WebPartZone1" runat="server">
</asp:WebPartZone>
</div>
<div>
<asp:WebPartZone ID="WebPartZone2" runat="server">
</asp:WebPartZone>
</div>
- In the design view, place something in each webpartzone (like a calendar, button, or wizard control)
<div>
<asp:WebPartZone ID="WebPartZone1" runat="server">
<ZoneTemplate>
<asp:Calendar ID="Calendar1" runat="server" />
</ZoneTemplate>
</asp:WebPartZone>
</div>
<div>
<asp:WebPartZone ID="WebPartZone2" runat="server">
<ZoneTemplate>
<asp:Button ID="Button1" runat="server" Text="Button" />
</ZoneTemplate>
</asp:WebPartZone>
</div>
- Set your dropdown list to AutoPostBack and then double click it to create an event handler
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true"
onselectedindexchanged="DropDownList1_SelectedIndexChanged1">
</asp:DropDownList>
- Switch to your code-behind
- Change your code to this
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// Set up the list of options
foreach (WebPartDisplayMode mode in this.WebPartManager1.SupportedDisplayModes)
// Add an item for each mode
this.DropDownList1.Items.Add(
new ListItem(mode.Name, mode.Name));
}
this.WebPartManager1.DisplayMode =
this.WebPartManager1.SupportedDisplayModes[
this.DropDownList1.SelectedValue];
}
protected void DropDownList1_SelectedIndexChanged1(
object sender, EventArgs e)
{
this.WebPartManager1.DisplayMode =
this.WebPartManager1.SupportedDisplayModes[
this.DropDownList1.SelectedValue];
}
Explaination
The first time the page loads, the dropdown will populate with the different display modes of the WebPartManager. The WebPartManager handles all of the cool drag and drop functionality. With every page load, the WebPartManager is set to the display mode specified by the dropdown. The eventhandler just changes the display mode of the WebPartManager.
If you run this code in IE, you will see your dropdown with options. If you select the Design options, you can move the controls inside the WebPartZone to another WebPartZone. In Firefox, this functionality isn’t there, but we will enable it in the next article.
Conclusion
This is the simple hello world application with WebParts. In the near future, we will cover more advanced topics in WebParts as well as how and where to integrate them into your application.
I noticed that when I used the CollapsiblePanelExtender, it had a tendancy to flicker once when the page loads. Here is my quick fix for that. All you have to do is add these properties to the panel's definition:
style="overflow:hidden" Height="0"
I hope this helps.
For archive purposes, I am posing a custom, generic, sortable, event-driven, doubly-linked list. In the future I will run some tests on it to see if it beats the current linked list implementation provided by the .NET framework. For those unsure of what a linked list is, here is a small tutorial on it.
Collections
When programming a computer, it is very common to store many items of the same type. Some different types of storing methods include array's, lists, and linked lists. The array is probably the most common for those attempting to store items. When an array of items is specified, the computer goes into memory and searches for a place to allocate the array. If it cannot allocate the entire array, it will keep searching. until it can.
Note: I put 5 spaces in the array definition. This is because of a manifest placed in the array, however, the inter workings of memory is beyond the scope of this article.
Now the problem with the array rises when someone runs out of room in their array. If they have an array that is 5 items large, and they want to hold a 6th, they must now re-define an entirely new array that can hold the new information. This requires the computer to go through and find another spot in memory that is big enough, place the new array in there, and then copy the elements from the original array to the new array. This problem is where a linked list comes in handy.
The Linked List
When a linked list is used, every item is stored in a chain of items. The linked list works by housing the references to the next (and previous in doubly linked lists) items in the chain. To do this, it is common to house your value inside a node. That node contains a reference in memory to the next node. Thus, you can define nodes anywhere you want in memory as long as you link to it making it easy to add and remove any amount of elements in the chain. The code would look something like this if you are trying to store integers:
public class LinkedList
{
Node firstNode;
public class Node
{
Node previous;
Node next;
int value;
}
}
Problems
With anything in computer science, there are downfalls to using Linked Lists. In order to get to an element in the linked list, you must traverse the entire list until you get to that element. This can be time consuming if there are a lot of nodes. Another problem is if you lose a reference to one of the nodes, you break the entire list. However, in a lot of circumstances, it is very useful to be able to add and remove items on the fly just by changing references.
Source
Here is an example doubly linked list example that I wrote. Thank dusda for the event driven idea. It is a doubly linked list that will convert to an array if needed. It supports any data type, and automatically sorts if specified. There is even support for getting an item by it's location (index). I hope you all find it useful.
using System;
namespace Systepic.Collections
{
/// <summary>
/// Event Handler designed to be thrown
/// when a collection's list items change.
/// </summary>
/// <param name="sender">The list that
/// fired the event.</param>
/// <param name="e">Information about
/// what the event did.</param>
public delegate void CollectionEventHandler(
Object sender, CollectionEventArgs e);
/// <summary>
/// Class inheriting from EventArgs designed
/// to hold information about the state change
/// of a collection.
/// </summary>
public class CollectionEventArgs : EventArgs
{
public CollectionEventArgs():base(){}
}
/// <summary>
/// A generic sortable linked list.
/// </summary>
/// <typeparam name="T">The type
/// that the linked list is. The type
/// should be a valuetype or a string
/// in order to be sorted.</typeparam>
public class LinkedList<T>
{
/// <summary>
/// An event fired whenever the collection
/// contents change.
/// </summary>
public event CollectionEventHandler ListChanged;
/// <summary>
/// The initial node to iterate in the list.
/// </summary>
private Node<T> firstNode;
/// <summary>
/// The number of items in the linked list.
/// </summary>
private int count;
/// <summary>
/// Whether or not it is a sorted list.
/// </summary>
private bool sorted;
/// <summary>
/// Create a new unsorted
/// linked list.
/// </summary>
public LinkedList() : this(false) { }
/// <summary>
/// Create a new linked list that
/// can be a sorted linked list.
/// </summary>
/// <param name="sorted">Whether or not
/// the linked list should be sorted.</param>
public LinkedList(bool sorted)
{
this.count = 0;
this.sorted = sorted;
}
/// <summary>
/// Adds an item to the end of the current
/// linked list. If the linked list is a
/// sorted list, the list is re-sorted.
/// </summary>
/// <param name="item">The item that should
/// be added to the linked list.</param>
/// <returns>Whether or not the item was
/// added successfully.</returns>
public bool Add(T item)
{
// Add if there is none
if (this.count == 0)
this.firstNode = new Node<T>(item);
else
{
Node<T> temp = this.firstNode;
for (int x = 1; x < this.count; ++x)
temp = temp.Next;
// Add a new item to the list
temp.Next = new Node<T>(
item, temp, null);
}
// increment the counter.
++count;
if (this.sorted) this.Sort();
// fire the event
if (this.ListChanged != null)
this.ListChanged(this,
new CollectionEventArgs());
// Call the insertAt method.
return true;
}
/// <summary>
/// Insert an item at a specified index in
/// the linked list. If the linked list is
/// a sorted list, the list is re-sorted.
/// </summary>
/// <param name="item">The item to add to the
/// linked list.</param>
/// <param name="index">The 0 based index of where
/// it should be added at.</param>
/// <returns>Whether or not the item was added
/// successfully.</returns>
public bool InsertAt(T item, int index)
{
// make sure the index is valid
if (index < 0)
throw new IndexOutOfRangeException();
if (index >= this.count)
throw new IndexOutOfRangeException();
// make sure there is an actual place to insert
if (count == 0)
return false;
// Create temp node to store info
Node<T> tempNode = new Node<T>(item);
// Create a temporary for iteration
Node<T> temp = this.firstNode;
// get to the specified index
for (int x = 1; x <= index; ++x)
temp = temp.Next;
// get the current reference.
if (index > 0)
{
Node<T> prev = temp.Previous;
prev.Next = tempNode;
tempNode.Previous = prev;
}
// set the references
tempNode.Next = temp;
temp.Previous = tempNode;
if (index == 0)
this.firstNode = tempNode;
// update the list information
++count;
if(this.sorted) this.Sort();
// fire event
if (this.ListChanged != null)
this.ListChanged(this,
new CollectionEventArgs());
return true;
}
/// <summary>
/// Find a particular item and remove
/// it from the linked list.
/// </summary>
/// <param name="item">The item to find
/// in the list.</param>
/// <returns>Whether or not the item
/// was removed successfully.</returns>
public bool Remove(T item)
{
// make sure we can remove
if (count < 1)
return false;
Node<T> temp = this.firstNode;
// Iterate and find item
for (int x = 1; x <= this.count; ++x)
{
if ((item as object) == (temp.Value as object))
{
// Change the references
if (temp.HasNext && temp.HasPrevious)
{
temp.Previous.Next = temp.Next;
temp.Next.Previous = temp.Previous;
}
else if (temp.HasNext)
temp.Next.Previous = null;
else if (temp.HasPrevious)
temp.Previous.Next = null;
else
temp = null;
// Reset the first Node if we
// removed it.
if (x == 1 && temp != null)
this.firstNode = temp.Next;
// Handle the counter
--count;
}
if (temp != null && temp.HasNext)
temp = temp.Next;
}
// Resort the algorithm if it is
// a sorted algorithm
if (this.sorted) this.Sort();
// fire event
if (this.ListChanged != null)
this.ListChanged(this,
new CollectionEventArgs());
return true;
}
/// <summary>
/// Sorts a list using insertion sort. Although
/// this algorithm is considered slow, since the
/// list is always almost sorted, the time to sort
/// the list is really fast whereas most high speed
/// algorithms will not beat this in this particular
/// instance because they handle near-sorted
/// algorithms the same as unsorted.
/// </summary>
/// <returns>Whether or not the
/// list was sorted successfully.</returns>
public bool Sort()
{
if (this.firstNode.Value is IComparable)
{
// check index out of range
if (this.firstNode.Next == null)
return true;
// get the base comparison
Node<T> baseNode = this.firstNode.Next;
// traverse the nodes
for (int x = 2; x <= this.count; ++x)
{
if ((baseNode.Previous.Value as
IComparable).CompareTo(
baseNode.Value) == 1)
{
Node<T> comp = this.firstNode;
bool found = false;
for (int y = 1; y < x && found != true; ++y)
{
if ((baseNode.Value as
IComparable).CompareTo(comp.Value) != 1)
{
// We need to change the references
// to all of the nodes to re-order them.
if (baseNode.HasNext)
{
baseNode.Next.Previous =
baseNode.Previous;
baseNode.Previous.Next =
baseNode.Next;
}
else
baseNode.Previous.Next = null;
baseNode.Next = comp;
if (comp.HasPrevious)
{
comp.Previous.Next =
baseNode;
baseNode.Previous =
comp.Previous;
}
else
baseNode.Previous = null;
comp.Previous = baseNode;
// the references are set... make
// sure the first node gets reset
// if needed.
if (y == 1)
this.firstNode = baseNode;
found = true;
}
// Set the next node
if (comp.HasNext)
comp = comp.Next;
}
}
// Set the next node
if (baseNode.HasNext)
baseNode = baseNode.Next;
}
return true;
}
else
return false;
}
/// <summary>
/// Clears all of the items in the
/// list by removing the reference
/// to the first node. The remaining
/// nodes no longer have references to
/// the application and will be collected
/// by the GC.
/// </summary>
public void Clear()
{
// kill the reference
this.firstNode = null;
// reset the count
this.count = 0;
// let everyone know.
if (this.ListChanged != null)
this.ListChanged(this,
new CollectionEventArgs());
}
/// <summary>
/// Converts the linked list to
/// an array.
/// </summary>
/// <returns>An array of the items
/// in the linked list ordered by
/// their location in the list top
/// down.</returns>
public T[] ToArray()
{
if (this.count < 1)
return default(T[]);
T[] newArray = new T[this.count];
// create a temp node
Node<T> temp = this.firstNode;
newArray[0] = temp.Value;
// iterate and get the node
for (int x = 1; x < this.count; ++x)
{
temp = temp.Next;
newArray[x] = temp.Value;
}
return newArray;
}
/// <summary>
/// Allows the use of this linked list
/// like it is an array. Get an item
/// in the linked list by it's location
/// in the list.
/// </summary>
/// <param name="index">The 0 based location
/// of the item to get in the list.</param>
/// <returns>The item at the specified
/// location.</returns>
public T this[int index]
{
get
{
// make sure we can do it before traversal.
if (index + 1 > count)
throw new IndexOutOfRangeException();
// create a temp node
Node<T> temp = this.firstNode;
// iterate and get the node
for (int x = 1; x <= index; ++x)
temp = temp.Next;
// return the node value
return temp.Value;
}
set
{
// make sure we can do it before traversal.
if(index + 1 > count)
throw new IndexOutOfRangeException();
// create a temp node
Node<T> temp = this.firstNode;
// iterate and get the node
for (int x = 0; x < index; ++x)
temp = temp.Next;
// set the node to value
temp.Value = value;
}
}
/// <summary>
/// How many nodes are contained in the
/// Linked List.
/// </summary>
public int Length
{
get { return this.count; }
}
/// <summary>
/// Whether or not this list sorts
/// automatically.
/// </summary>
public bool IsSorted
{
get { return this.sorted; }
set { this.sorted = value; }
}
/// <summary>
/// Generic node with pre and post references
/// for use in a linked list.
/// </summary>
/// <typeparam name="U">The type of
/// information contained within the node.</typeparam>
private class Node<U>
{
/// <summary>
/// The node reference to the node
/// before this node reference.
/// </summary>
Node<U> pre;
/// <summary>
/// The node reference to the node after
/// this node reference.
/// </summary>
Node<U> post;
/// <summary>
/// The generic information stored within
/// the node.
/// </summary>
U assignment;
/// <summary>
/// Create a new node with references
/// to both sides of the node.
/// </summary>
/// <param name="info">What the node actually
/// contains.</param>
/// <param name="previous">The node before this
/// node.</param>
/// <param name="next">The node after this
/// node.</param>
public Node(U info, Node<U> previous, Node<U> next)
{
this.assignment = info;
this.pre = previous;
this.post = next;
}
/// <summary>
/// Create a new node with no references
/// to nodes.
/// </summary>
/// <param name="info">The information
/// that the node actually contains.</param>
public Node(U info) : this(info, null, null) { }
/// <summary>
/// The node before this node in the chain.
/// </summary>
public Node<U> Previous
{
get { return this.pre; }
set { this.pre = value; }
}
/// <summary>
/// The node after this node in the chain.
/// </summary>
public Node<U> Next
{
get { return this.post; }
set { this.post = value; }
}
/// <summary>
/// Whether or not the node has a node
/// reference to the previous node.
/// </summary>
public bool HasPrevious
{
get { return (this.pre == null) ? false : true; }
}
/// <summary>
/// Whether or not the node has a node
/// reference to the next node.
/// </summary>
public bool HasNext
{
get { return (this.post == null) ? false : true; }
}
/// <summary>
/// The actual value stored in this node.
/// </summary>
public U Value
{
get { return this.assignment; }
set { this.assignment = value; }
}
}
}
}
Overview
I was originally going to just post the information needed for my
reference, but I decided that I had to reference many things all the
time, so I will just post a tutorial. For those people using ASP.NET
often on a large amount of projects have no doubt-ably come across
ASP.NET 2.0's custom roles and membership tools. These tools allow you
to use a lot of prefabricated tools written by the Microsoft developers
in order to perform menial tasks like authentication and role
assignment. The problem is that this system is so flexible, it is hard
to get a lot of documentation about using all of the features, and
searchers are usually pointed to specific information. This tutorial is
going to be short and sweet and demonstrate what I feel would be the
most common and useful usage for the membership and role system.
Our task: A custom authentication system implementing users and roles.
Our technologies: ASP.NET 2.0 written in C# (Visual Studio) using a SqlServer 2005 database.
Setting up the database
Origonally, I was under the assumtion that unless I wrote my own custom
membership and role classes, I would be required to use the ASPNETDB on
SqlExpress (I later found out that a lot of people were under the same
assumption). Well I have no intention of writing unnessissary code, and
I found out that there is a tool that will set up a remote database
according to the specifications of Microsoft's default membership and
role providers. so...
- Run the Visual Studio Command Prompt
- Type aspnet_regsql and press enter
- Go through the wizard provided to set up your database
This will set up your database with all of the stored procedures and tables required. Very fast eh? Onward...
Setting up the website
- Create a new ASP.NET website or open up the existing site.
- Create a new or open up your web.config files
Use the following in your web.config under the <configuration> section
<connectionStrings>
<add name="TestConnection"
connectionString="your connection string here"/>
</connectionStrings>
This section is the connection string for your SqlServer2005 server that you previously configured. It will be used by our membership and roles declarations below. Add the following too your web.config file under the <system.web> section
<roleManager enabled="true" defaultProvider="MyTestRoleProvider">
<providers>
<clear />
<add connectionStringName="TestConnection"
applicationName="/ApplicationName"
name="MyTestRoleProvider"
type="System.Web.Security.SqlRoleProvider" />
</providers>
</roleManager>
<membership defaultProvider="MyTestMembershipProvider"
userIsOnlineTimeWindow="20"
hashAlgorithmType="MD5">
<providers>
<clear />
<add name="MyTestMembershipProvider"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/ApplicationName"
requiresUniqueEmail="true"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="6"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
passwordStrengthRegularExpression=""
connectionStringName="TestConnection"
type="System.Web.Security.SqlMembershipProvider" />
</providers>
</membership>
<authentication mode="Forms" />
A little explaination of the above. This section configures your asp.net to handle your new Sql connection with custom membership and roles. The <roleManager> section creates a custom role provider that will be used by asp.net to handle... well roles. The <membership> section defines a custom membership provider that asp.net will use to manage your users. The settings within the TestMembership declaration should be fairly straight forward to control your application as much as possible. That last little bit, just lets ASP.net know that you are using custom authentication.
Now you can use all of the authentication controls within asp.net using SqlServer2005 as well as the nifty ASP.net Web Site Administration Tool.
Happy Coding.
Problem
I was working on a remoting project for an assignment and we came
across a problem in 2.0. As of 2.0 you cannot make cross-thread calls
to a windows forms control. This means that if you are doing an
asyncronous call, most likely, unless your polling the async result, it
will come back on a different thread and you cannot change a windows
form or the controls on it without coming back to the origonal thread.
This is fine if you are making all of your asyncronous calls on the
actual form (You just need to call the Invoke method), but if you are
seperating the asyncronous logic from the presentation layer (Which is
recommended), any results processed from that logic can be difficult to
update in windows forms. Fortunatly, there is a solution within the
AsyncOperation class. I recommend looking into this class if you are
doing anything thread related, but I created a wrapper around the class
to make it a bit easier to use. Hopefully, it will be as useful to you
as it was for me.
How it works
My wrapper simply operates the AsyncOperation class. When you
instantiate the object, you instantiate a copy of the AsyncOperation
class which will hold a reference to the initial thread you
instantiated it on. This means you can make cross-thread calls to it,
and it will execute the code on the origonal thread it was instantiated
on. So, if you instantiate this class within your dll's constructor,
any events or code that you execute that need to work on the windows
forms thread you just call in an anonymous delegate under the
Syncronize method.
Place this class somewhere in your project.
using System;
using System.ComponentModel;
using System.Threading;/// <summary>
/// Class that allows multithread syncronization
/// from asyncronous calls. Anything wrapped with
/// the syncronize method will be executed on the
/// same thread as where the AsyncSyncronizer
/// is instantiated.
/// </summary>
/// <example>
/// Instantiate on thread you want to use
/// AsyncSyncronizer sync = new AsyncSyncronizer();
///
/// // Run on the code you would like to execute.
/// this.sync.Syncronize(
/// delegate
/// {
/// /*Code to Execute*/
/// });
///</example>
public class AsyncSyncronizer
{
/// <summary>
/// Delegate pointing to code executed
/// within the Syncronize method.
/// </summary>
public delegate void AsyncDelegate();/// <summary>
/// Async operation which will push execution
/// to the proper thread.
/// </summary>
private AsyncOperation operation;/// <summary>
/// Creates an object of the AsyncSyncronizer
/// Everything wrapped within the Syncronize
/// method will be executed by default on the
/// thread this is instantiated on. In order to change
/// the thread, run SetThread.
/// </summary>
public AsyncSyncronizer()
{
// Set to this thread.
this.SetThread();
}/// <summary>
/// Sets the thread code will by syncronized to
/// to the current thread running.
/// </summary>
public void SetThread()
{
this.operation =
AsyncOperationManager.CreateOperation(null);
}/// <summary>
/// Runs code within this method on the
/// thread either set by set thread or
/// where the object was instantiated.
/// </summary>
/// <param name="render">The code
/// to execute on the specified thread.</param>
public void Syncronize(
AsyncDelegate render)
{
this.operation.Post(new SendOrPostCallback(delegate(object state)
{
render();
}), null);
this.operation.OperationCompleted();
}
}
I encountered a terrible bug in Visual Studio when I installed my DirectX SDK for summer 2006. All of my keyboard configurations were erased, and I couldn't even use my backspace key. The problem occurred in the beta, and supposedly there was a patch released. Anyways, here is how you fix it.
- C:\Documents and Settings\<Your Username>\Application Data\Microsoft\VisualStudio\8.0
- Delete all files
- Open Visual Studio
- Tools->Import and Export Settings
- Reset all settings
- Select "No, just reset settings"