Monday, November 8, 2010

Location of ClickOnce Installation Files

C:\Documents and Settings\USERNAME\Local Settings\Apps\2.0
 

Friday, November 5, 2010

Show or hide file extensions

A file name extension is a set of characters added to the end of a file name that determine which program should open it. Follow these steps to choose whether Windows displays these file extensions.

  1. Open Folder Options by clicking the Start button Picture of the Start button, clicking Control Panel, clicking Appearance and Personalization, and then clicking Folder Options.

  2. Click the View tab, and then, under Advanced settings, do one of the following:

    • To hide file extensions, select the Hide extensions for known file types check box, and then click OK.

    • To display file extensions, clear the Hide extensions for known file types check box, and then click OK

Reference in the manifest does not match the identity of the downloaded assembly

If you try to reference an executable or a project with an executable you get an error when you try to update the application via ClickOnce.
 
The errror I got was:
"Reference in the manifest does not match the identity of the downloaded assembly"
 
The fix was found here:
 
And below are the steps:

I have test it with Visual Studio 2008 RTM, it works well now. The following steps are my test procedures.

1. Create a solution with two Windows Application projects, WinAppA and WinAppB.

2. Set WinAppA as publish project and add a reference to the WinAppB.

3. Open WinAppB properties window.

4. Click Signing tab, sign the ClickOnce manifests.

5. Click Security tab, enable the ClickOnce security settings.

6. Publish the WinAppA, publish well.

7. Test published WinAppA, it works well.

 

 

Bitmaps in WPF, disposing of bitmaps in WPF and other issues

The first thing is in WPF you can't set the Source of an Image Control to that of a Bitmap, you need to use the BitmapImage
 
 
This gives you a build error:
Image I = new Image(@"C:\Users\Public\Pictures\Sample Pictures\Penguins.bmp");
Imagecontrol.Image.Source = I
 
But this works:
Image I = new Image();
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(@"C:\Users\Public\Pictures\Sample Pictures\Penguins.bmp", UriKind.Absolute);
bi.EndInit();
Imagecontrol.Image.Source  = bi;
 
The problem with the above code is that whenever I used it and subsequently tried to delete the file Penguins.jpg or move it, I got an exception.  It seems like we were holding a lock on the file.  So the fix was to do the following:
 

      Imagecontrol.Image.Source = LoadImage(@"C:\Users\Public\Pictures\Sample Pictures\Penguins.bmp");

      private BitmapImage LoadImage(string myImageFile)
        {
            BitmapImage myRetVal = null;
            if (myImageFile != null)
            {
                BitmapImage image = new BitmapImage();
                using (FileStream stream = File.OpenRead(myImageFile))
                {
                    image.BeginInit();
                    image.CacheOption = BitmapCacheOption.OnLoad;
                    image.StreamSource = stream;
                    image.EndInit();
                }
                myRetVal = image;
            }
            return myRetVal;
        }

Monday, October 4, 2010

Have Log4Net generate the log files to another location besides the Program Files


- To have log4net write to the temp directory
http://stackoverflow.com/questions/1524340/how-to-get-log4net-to-generate-log-files-when-running-as-non-administrator-user

  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="${TMP}\log.txt" />
    <appendToFile value="true" />
    <rollingStyle value="Size" />
    <maxSizeRollBackups value="10" />
    <maximumFileSize value="100KB" />
    <staticLogFileName value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%-5level [%date] %message%newline" />
    </layout>
  </appender>


or     <file value="${HOMEPATH}\log.txt" />

Wednesday, June 30, 2010

app.config and user.config FAQ

A great tutorial and insight into the app.config file and user.config file

http://blogs.msdn.com/b/rprabhu/archive/2005/06/29/433979.aspx


One of the cool new features in .NET 2.0/VS 2005 is an easy to use,
extensible API to manage application/user settings, i.e., data that
needs to be persisted across runs of a client application. You can
find more information about this feature on MSDN or in my earlier blog
posts on this topic.

While the feature is easy to use in general, we often get questions
from users trying more advanced scenarios about why a certain aspect
of the feature works in a particular way or how to customize some
behavior. The answers to these questions are generally in the MSDN
docs, but can sometimes be hard to find. I thought it would be useful
to cover this information in a FAQ for easy future reference. I will
be updating the FAQ as and when there are more questions to add.

Q: I notice there are two kinds of settings - application scoped and
user scoped. Application scoped settings seem to be read-only and I
cannot change them at runtime. Why is that?

A: There are two main types of settings that applications generally
want to store: (1) certain data like connection strings and web
references that don't change often, but should be possiblep for an
admin to change and therefore cannot be hardcoded into the application
and (2) user preferences and customization that can change any time.
Application scoped settings are useful in scenario (1) and user scoped
settings, in the latter. They are essentially read only from tche
application's point of view and aren't meant to be changed by the
user, but admins could go and edit the file if they want to. An
additional reason for this has to do with how the default
SettingsProvider stores settings - application scoped settings go in
the exe configuration file and user scoped settings in user.config
files located in the user data path. Generally, exe config files
shouldn't be written to at runtime by the application, since the user
may not have access to them (if the application is installed in
c:\Program Files\..., only privileged users have access, for example).
Even if they do, it is not usually a good idea for a user to control
changing a file that affects every other user of the application.

Q: You said user.config files go in the user data path. How can I
locate the file? Are there multiple files for an application or just
one?

A: As mentioned before, the default SettingsProvider for client
applications (called the LocalFileSettingsProvider) stores settings in
the application configuration files. In .NET v1 and v1.1, there were
two levels of config files - machine.config and app.exe.config (where
'app.exe' is the name of the application). In v2.0, we have added two
more levels of configuration to store user specific data - one that
goes in the roaming user profile path and another in the local user
profile path. On XP, the profile directories would be something like
'c:\Documents and Settings\<username>\Application Data' and
'c:\Documents and Settings\<username>\Local Settings\Application Data'
respectively. These directories are the recommended location (per
Windows Logo requirements) for storing user specific information and
most applications (like Outlook and Visual Studio) put user data
somewhere under here.

The exact path of the user.config files looks something like this:

<Profile Directory>\<Company Name>\<App Name>_<Evidence
Type>_<Evidence Hash>\<Version>\user.config

where

<Profile Directory> - is either the roaming profile directory or the
local one. Settings are stored by default in the local user.config
file. To store a setting in the roaming user.config file, you need to
mark the setting with the SettingsManageabilityAttribute with
SettingsManageability set to Roaming.

<Company Name> - is typically the string specified by the
AssemblyCompanyAttribute (with the caveat that the string is escaped
and truncated as necessary, and if not specified on the assembly, we
have a fallback procedure).

<App Name> - is typically the string specified by the
AssemblyProductAttribute (same caveats as for company name).

<Evidence Type> and <Evidence Hash> - information derived from the app
domain evidence to provide proper app domain and assembly isolation.

<Version> - typically the version specified in the
AssemblyVersionAttribute. This is required to isolate different
versions of the app deployed side by side.

The file name is always simply 'user.config'.

If you want to get to the path programmatically, you can do it using
the Configuration Management API (you need to add a reference to
System.Configuration.dll). For example, here is how you can get the
local user.config file path:

Configuration config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
Console.WriteLine("Local user config path: {0}", config.FilePath);

Q: Why is the path so obscure? Is there any way to change/customize it?

A: The path construction algorithm has to meet certain rigorous
requirements in terms of security, isolation and robustness. While we
tried to make the path as easily discoverable as possible by making
use of friendly, application supplied strings, it is not possible to
keep the path totally simple without running into issues like
collisions with other apps, spoofing etc.

The LocalFileSettingsProvider does not provide a way to change the
files in which settings are stored. Note that the provider itself
doesn't determine the config file locations in the first place - it is
the configuration system. If you need to store the settings in a
different location for some reason, the recommended way is to write
your own SettingsProvider. This is fairly simple to implement and you
can find samples in the .NET 2.0 SDK that show how to do this. Keep in
mind however that you may run into the same isolation issues mentioned
above .

Q: I deployed my application using Clickonce and saved some settings,
but can't find the user.config file.

A: The path algorithm mentioned above is not used in the Clickonce
case. Instead, the local user.config file goes in the Clickonce Data
directory (the <Version> part of the path will still be included).
There is no roaming user.config file for Clickonce applications.

Q: How are my strongly typed properties serialized as settings? I
couldn't get the <insert type here> class to serialize correctly.

A: There are two primary mechanisms that ApplicationSettingsBase uses
to serialize settings - (1) If a TypeConverter exists that can convert
to and from string, we use it. (2) If not, we fallback to the
XmlSerializer. While most common types can be serialized in one of
these ways, there are some types that may not. In such cases, you have
a few different options:

* Implement a TypeConverter for the type that can convert to and
from string. The implementation can use a suitable serialization
mechanism like one of the formatters/serializers that ship in the
Framework or any custom mechanism you wish. You can then specify this
converter on the type itself or on the property in your settings
class.
* Specify a particular SettingsSerializeAs enum value using a
SettingsSerializeAsAttribute. For example, if you wish to serialize a
setting in binary format, simply specify SettingsSerializeAs.Binary.

Q: My application has a few user scoped settings, but I notice Visual
Studio puts them in app.config. I thought they go in user.config
files?

A: The configuration system is hierarchical and has this ordering:
machine -> application -> roaming user -> local user. When you query a
configuration section at any level, you get a merged view of the
sections declared in that level and those below it (with machine being
the lowest level and local user the highest). The section handler
defines how the merge happens and for settings, a setting value
specified in, say, local user config trumps the one specified in
application config.

So for user scoped settings, you can think of the values specified in
app.config to be install time defaults. When the settings are saved
into user.config, those values will override these defaults. This way
admins have the option of changing the defaults. Note that the
defaults can also be specified by means of a
DefaultSettingValueAttribute. The provider will use this value if no
value is specified for a setting in any level of config.

Q: Why is there a version number in the user.config path? If I deploy
a new version of my application, won't the user lose all the settings
saved by the previous version?

A: There are couple of reasons why the user.config path is version
sensitive. (1) To support side-by-side deployment of different
versions of an application (you can do this with Clickonce, for
example). It is possible for different version of the application to
have different settings saved out. (2) When you upgrade an
application, the settings class may have been altered and may not be
compatible with what's saved out, which can lead to problems.

However, we have made it easy to upgrade settings from a previous
version of the application to the latest. Simply call
ApplicationSettingsBase.Upgrade() and it will retrieve settings from
the previous version that match the current version of the class and
store them out in the current version's user.config file. You also
have the option of overriding this behavior either in your settings
class or in your provider implementation.

Q: Okay, but how do I know when to call Upgrade?

A: Good question. In Clickonce, when you install a new version of your
application, ApplicationSettingsBase will detect it and automatically
upgrade settings for you at the point settings are loaded. In
non-Clickonce cases, there is no automatic upgrade - you have to call
Upgrade yourself. Here is one idea for determining when to call
Upgrade:

Have a boolean setting called CallUpgrade and give it a default value
of true. When your app starts up, you can do something like:

if (Properties.Settings.Value.CallUpgrade) {
Properties.Settings.Value.Upgrade();
Properties.Settings.Value.CallUpgrade = false;
}

This will ensure that Upgrade() is called only the first time the
application runs after a new version is deployed.

Update: 12/10/2005

Q: Is there a way to access settings from the configuration files if I
don't have a reference to the settings class that owns them?

A: Yes, you might sometimes require to access certain settings, but
you don't have access to the settings class itself. For example, the
default settings class generated by the settings designer in VS 2005
is internal to the assembly it is defined in. What if you need to
access some settings from a different assembly, let's say, a dll that
is loaded by your application? The settings API provides a useful
mechanism for this through the SettingsGroupNameAttribute. Usually,
the settings provider uses the fully qualified name of your settings
class as the key to isolate your settings from those belonging to
other classes. This attribute allows you to access settings with a
different key or 'group name'. So to access settings from the
application's settings class, all the dll needs to do is define its
own settings class with properties that match the other class, and
apply a SettingsGroupNameAttribute, giving it the other class' name as
the group name. A small caveat: if you want to do this in VS, make
sure you apply the attribute to the user partial class you get to by
clicking 'View Code', and not the designer owned partial class, since
any changes to the latter can get overwritten by the settings
designer.

Q: Wait, you might ask, this is a rather powerful capability. Is it a
security hole? Someone might access my settings without my knowledge
or permission!

A: Well, this isn't really a security hole for two reasons:

*
From a security point of view, isolation is provided at the app
domain level. The CLR recommended way of hosting untrusted code is to
load it in a separate app domain. When you create an app domain, you
can specify a unique friendly name for it and point it to an
application configuration file of your choice. The unique friendly
name ensures that the app domain gets separate user configuration
files as well. Thus, the code cannot access your settings, since it
doesn't have access to your configuration files. Conversely, any code
that has access to your configuration files can access the settings
without using the SettingsGroupNameAttribute anyway, since it can use
the low level configuration APIs to do so (this requires
ConfigurationPermission for read though, and much higher permissions
for write).
*
If you are really paranoid and don't want users of the
application or anyone else, including code running in the same app
domain as your settings class, to be able to read your settings
outside of your class, you can choose to encrypt the settings before
pushing them to the provider, and decrypt when you read them out. The
settings API does not provide any specific way to do this, but you can
use the crypto API in the .NET Framework. The configuration API also
has the ability to encrypt configuration sections - see this article
for more information.

Q: Does all this mean I cannot access settings in partial trust?

A: Not at all. We have done the work to ensure you can safely access
your settings in partial trust. In fact, this should 'just work' for
you in terms of reading and writing user scoped settings from your
application. The only difference is that you cannot write out an
unlimited amount of data, for obvious reasons. The number of bytes you
can write through the settings API (specifically, the
LocalFileSettingsProvider) in partial trust is restricted by an admin
controlled quota, which is specified by the IsolatedStoragePermission
class. This is just like how Isolated Storage itself works.

Q: You mentioned the configuration API a couple of times. What is this
and how is it different from the settings API? I am a little confused.

A: There is a fundamental distinction between the settings API and the
configuration API. The former provides an object model to manage
application settings. This model uses a provider based storage scheme,
so the storage aspect is abstracted away. Where the settings are
stored is a provider specific detail - it could store them in raw
files, in SQL server, in the registry or call a remote web service to
retrieve them. The default settings provider we ship happens to use
configuration to store settings, since that's the most obvious store
for settings in client applications. The configuration API is a little
more low level and lets you create and update configuration sections
in config files. So in some sense, the settings API sits on top of
configuration.

So if what you want to do is store application settings and user
preferences, then the settings API is the way to go. If you really
need to implement configuration sections and/or access certain
sections in config directly, use the configuration API.

Q: Is the settings functionality available only to Windows Forms applications?

A: The settings API itself has no restrictions at all - you can use it
in any kind of application - client, web, VSTO, console, WPF etc. The
default settings provider, LocalFileSettingsProvider, uses
configuration to store settings, so it has certain limitations. For
example, ASP.NET applications do not have user.config files, so you
cannot write user scoped settings in web applications using this
provider. Ofcourse, you can use the Profiles feature in ASP.NET 2.0 to
very conveniently store user scoped settings. User.config files are
also not supported for VSTO apps (in general, where the host
application is native, like Outlook, Word or even IE). In these cases,
you will need to write your own settings provider (which is quite easy
to do, by the way, and there are good samples and docs in MSDN that
describe how to do this) to be able to read/write user scoped
settings. For the basic kinds of managed client applications like
console, Windows Forms and WPF however, the LocalFileSettingsProvider
is fully supported.

Other approaches to create single instance

http://stackoverflow.com/questions/19147/what-is-the-correct-way-to-create-a-single-instance-application
http://rrelyea.spaces.live.com/blog/cns!167AD7A5AB58D5FE!1834.entry

Making your WPF application single instance

I used the ideas in this article. However, when bringing my
application to the top, I used my own methods. Below is the link to
the article, and the code that I used.
http://sanity-free.org/143/csharp_dotnet_single_instance_application.html

However, I used the following:
In my Startup.cs file I did the following:

static Mutex mutex = new Mutex(true,
"{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
[STAThread]
public static void Main()
{
try
{
if (mutex.WaitOne(TimeSpan.Zero, true))
{
MyApp app = new MyApp
app.InitializeComponent();
app.Run();
mutex.ReleaseMutex();
}
else
{
// send our Win32 message to make the currently
running instance
// jump on top of all the other windows
NativeMethods.BringTMForeGround();
}
}
catch (Exception e)
{//Catch all un-handle exception from the application

}
}

And in my NativeMethods.cs I did the following:
[DllImport("User32", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string lpClassName, string
lpWindowName);

[DllImport("User32", EntryPoint = "BringWindowToTop")]
public static extern bool BringWindowToTop(IntPtr wHandle);

[DllImport("User32", EntryPoint = "SetForegroundWindow")]
public static extern bool SetForegroundWindow(IntPtr wHandle);

[DllImport("User32", EntryPoint = "SetFocus")]
public static extern bool SetFocus(IntPtr wHandle);

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

public static void BringTMForeGround()
{
try
{
bool ret = false;
IntPtr hWnd = NativeMethods.FindWindow(null, "Title of
Application Window"); // Get Window of App2

if (hWnd == IntPtr.Zero)
{
FindWindowLike.Window[] list = FindWindowLike.Find(0, "Title
of Application Window", "");
if (list.Length >= 1)
hWnd = (IntPtr)list[0].Handle;
}
if (hWnd != IntPtr.Zero) // Check if App2 exists
{
ret = NativeMethods.SetForegroundWindow(hWnd);
ret = NativeMethods.ShowWindow(hWnd, 9);
ret = NativeMethods.BringWindowToTop(hWnd);
//ret = SetFocus(hWnd);
}
}
catch (Exception)
{
}
}


The function FindWinowLike was another class and this is whats in it:
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Text;

namespace MyAppNamespace
{
public class FindWindowLike
{

public class Window
{
public string Title;
public string Class;
public int Handle;
}

[DllImport("user32")]
private static extern int GetWindow(int hwnd, int wCmd);

[DllImport("user32")]
private static extern int GetDesktopWindow();

[DllImport("user32", EntryPoint = "GetWindowLongA")]
private static extern int GetWindowLong(int hwnd, int nIndex);

[DllImport("user32")]
private static extern int GetParent(int hwnd);

[DllImport("user32", EntryPoint = "GetClassNameA")]
private static extern int GetClassName(
int hWnd, [Out] StringBuilder lpClassName, int nMaxCount);

[DllImport("user32", EntryPoint = "GetWindowTextA")]
private static extern int GetWindowText(
int hWnd, [Out] StringBuilder lpString, int nMaxCount);

private const int GWL_ID = (-12);
private const int GW_HWNDNEXT = 2;
private const int GW_CHILD = 5;

public static Window[] Find(int hwndStart, string findText, string
findClassName)
{

ArrayList windows = DoSearch(hwndStart, findText, findClassName);

return (Window[])windows.ToArray(typeof(Window));

} //Find


private static ArrayList DoSearch(int hwndStart, string findText,
string findClassName)
{

ArrayList list = new ArrayList();

if (hwndStart == 0)
hwndStart = GetDesktopWindow();

int hwnd = GetWindow(hwndStart, GW_CHILD);

while (hwnd != 0)
{

// Recursively search for child windows.
list.AddRange(DoSearch(hwnd, findText, findClassName));

StringBuilder text = new StringBuilder(255);
int rtn = GetWindowText(hwnd, text, 255);
string windowText = text.ToString();
windowText = windowText.Substring(0, rtn);

StringBuilder cls = new StringBuilder(255);
rtn = GetClassName(hwnd, cls, 255);
string className = cls.ToString();
className = className.Substring(0, rtn);

if (GetParent(hwnd) != 0)
rtn = GetWindowLong(hwnd, GWL_ID);

if (windowText.Length > 0 && windowText.StartsWith(findText) &&
(className.Length == 0 || className.StartsWith(findClassName)))
{
Window currentWindow = new Window();

currentWindow.Title = windowText;
currentWindow.Class = className;
currentWindow.Handle = hwnd;

list.Add(currentWindow);
}

hwnd = GetWindow(hwnd, GW_HWNDNEXT);

}

return list;

} //DoSearch

} //Class

}

Monday, June 28, 2010

What is in the bitmap header

from - http://local.wasp.uwa.edu.au/~pbourke/dataformats/bmp/

Header

The header consists of the following fields. Note that we are assuming
short int of 2 bytes, int of 4 bytes, and long int of 8 bytes. Further
we are assuming byte ordering as for typical (Intel) machines. The
header is 14 bytes in length.

typedef struct {
unsigned short int type; /* Magic identifier */
unsigned int size; /* File size in bytes */
unsigned short int reserved1, reserved2;
unsigned int offset; /* Offset to image data, bytes */
} HEADER;

The useful fields in this structure are the type field (should be
'BM') which is a simple check that this is likely to be a legitimate
BMP file, and the offset field which gives the number of bytes before
the actual pixel data (this is relative to the start of the file).
Note that this struct is not a multiple of 4 bytes for those
machines/compilers that might assume this, these machines will
generally pad this struct by 2 bytes to 16 which will unalign the
future fread() calls - be warned.
Information

The image info data that follows is 40 bytes in length, it is
described in the struct given below. The fields of most interest below
are the image width and height, the number of bits per pixel (should
be 1, 4, 8 or 24), the number of planes (assumed to be 1 here), and
the compression type (assumed to be 0 here).

typedef struct {
unsigned int size; /* Header size in bytes */
int width,height; /* Width and height of image */
unsigned short int planes; /* Number of colour planes */
unsigned short int bits; /* Bits per pixel */
unsigned int compression; /* Compression type */
unsigned int imagesize; /* Image size in bytes */
int xresolution,yresolution; /* Pixels per meter */
unsigned int ncolours; /* Number of colours */
unsigned int importantcolours; /* Important colours */
} INFOHEADER;

The compression types supported by BMP are listed below :

* 0 - no compression
* 1 - 8 bit run length encoding
* 2 - 4 bit run length encoding
* 3 - RGB bitmap with mask

Only type 0 (no compression will be discussed here.

How to find the image format of an image in C#

from stackoverflow -
http://stackoverflow.com/questions/1397512/find-image-format-using-bitmap-object-in-c
using(Image img = Image.FromFile(@"C:\path\to\img.jpg"))
{
if (img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg))
{
// ...
}
}

Proper way to rethrow an exception in c#

just do "throw;" don't do "throw ex" or something like that.

Monday, June 14, 2010

How to get a specific version or get a specific label from TFS to a different location

Create a new workspace and specify that workspace to have a different location

Unhandled exception in BackgroundWorker

I was using the BackgroundWorker in WPF and had an unhandled exception
there and needed a better way to deal with this error. This is how I
did it:
I used the RunWorkerCompleted event. In this event, if the e.Error !=
null, I set a string value ErrorMessage to the message, and I call a
function ErrorOccurred which then raises an event that my calling
application caught. Below is my code:

My main Class

This code is just put together and probably won't work, but should
give you the general idea. This is my Window that calls the
background worker. I have two events, Finished and Error. If the
Error occurs, I do something, if its finishes successfully I do
something else.
public partial class MainWindow : Window
{
private DoWork Worker = new DoWork();

public MainWindow()
{
InitializeComponent();
Worker.Finished += new FinishedEventHandler(Worker_Finished);
Worker.Error += new ErrorEventHandler(Worker_Error);
}

void Worker_Finished(object sender, EventArgs e, List<Response> rList)
{
//do something when finished
}
void Worker_Error(object sender, EventArgs e, string errorMessage)
{
//do something if error
}

private void btnWork_ItemClick(object sender, ClickEventArgs e)
{
if (!Worker.IsBusy())
{
Worker.DoWork();
}
}
}

This is my Worker class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows;

namespace MyNamespace
{
// A delegate type for hooking up when the backgroundworker is
finished. It returns the Response object
public delegate void FinishedEventHandler(object sender, EventArgs
e, List<Something> rList);
public delegate void ErrorEventHandler(object sender, EventArgs e,
string errorMessage);

public class DoWork
{

public BackgroundWorker worker;
List<Response> ResponseList;// = new List<Response>();
string ErrorMessage;


// An event that clients can use to be notified whenever the
// elements Backgroundworker is finished
public event FinishedEventHandler Finished;
public event ErrorEventHandler Error;

protected virtual void WorkCompleted(EventArgs e)
{
if (Finished != null)
Finished(this, e, ResponseList);
}

protected virtual void ErrorOccurred(EventArgs e)
{
if (Error != null)
Error(this, e, ErrorMessage);
}

/// <summary>
/// Main calls are
/// IsBusy, DoWork and CancelWork. It has a event called
FinishedEventHandler
/// that is raised when the work is completed
/// </summary>
public CheckResponse()
{
// Create a Background Worker
worker = new BackgroundWorker();

// Enable support for cancellation
worker.WorkerSupportsCancellation = true;
worker.DoWork +=
new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
}

/// <summary>
/// when the work is completed return anobject and set r to its value
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void worker_RunWorkerCompleted(
object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
ErrorMessage = "An error occurred. " + e.Error.Message;
ErrorOccurred(EventArgs.Empty);
}
else
{
ResponseList = (List<Response>)e.Result;
WorkCompleted(EventArgs.Empty);
}
}
/// <summary>
/// </summary>
/// <param name="sender"><param>
/// <param name="e"></param>
private void worker_DoWork(
object sender, DoWorkEventArgs e)
{
try
{
e.Result = Some call that returns a List
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}

/// <summary>
/// Returns the status of the Backgroundworker. if its busy or not
/// </summary>
/// <returns></returns>
public bool IsBusy()
{
return worker.IsBusy;
}
/// <summary>
/// Can be called to cancel a backgroundworker
/// </summary>
public void CancelWork()
{
worker.CancelAsync();
}
/// <summary>
/// If the backgroundworker is not busy it starts the worker.
/// </summary>
public void DoWork()
{
if (!worker.IsBusy)
{
worker.RunWorkerAsync();
}
}
}
}

Friday, June 11, 2010

Monday, May 17, 2010

Dealing with Unhandled exceptions in WPF

In you App.Xaml.cs file put the following:

private void App_DispatcherUnhandledException(object sender,
System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show("An unhandled " + e.Exception.GetType().ToString() +
" exception was caught and ignored.");
e.Handled = true;
}


Add the following to the App.xaml file

DispatcherUnhandledException="App_DispatcherUnhandledException"

to the Application tag of App.xaml like this:
<Application x:Class="Something.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml" Startup="Application_Startup"
DispatcherUnhandledException="App_DispatcherUnhandledException">

Dealing with Unhandled Exceptins in C#

http://www.switchonthecode.com/tutorials/csharp-tutorial-dealing-with-unhandled-exceptions

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace MyApp
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.ThreadException +=
new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}

static void CurrentDomain_UnhandledException
(object sender, UnhandledExceptionEventArgs e)
{
try
{
Exception ex = (Exception)e.ExceptionObject;

MessageBox.Show("Whoops! Please contact the developers with "
+ "the following information:\n\n" + ex.Message + ex.StackTrace,
"Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
finally
{
Application.Exit();
}
}

public static void Application_ThreadException
(object sender, System.Threading.ThreadExceptionEventArgs e)
{
DialogResult result = DialogResult.Abort;
try
{
result = MessageBox.Show("Whoops! Please contact the developers "
+ "with the following information:\n\n" + e.Exception.Message
+ e.Exception.StackTrace, "Application Error",
MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
}
finally
{
if (result == DialogResult.Abort)
{
Application.Exit();
}
}
}
}
}

Wednesday, April 7, 2010

Switch statements

In VB there was Select Case. In C# there is the switch statement.

The following is best practice on how you should handle cases that do
the same logic when hit.
using fall through on the case:

int x = 1;
switch ( x )
{
case 1:
case 2:
/* code here */
break;
case 3:
/* code here */
break;
default:
break;
}

The following while doable should not be used because it promotes
unreadable code, adding to complexity and potential for bugs:
Or use goto case statements:

int x = 1;
switch ( x )
{
case 1:
goto case 2;
case 2:
goto case 5;
break;
case 3:
/* code here */
break;
case 4:
goto case 2;
break;
case 5:
/* code here */
break;
case 6:
/* code here */
break;
case 7:
goto case 5;
break;
case 8:
/* code here */
break;
case 9:
goto case 2;
break;
default:
break;
}

How to use the dispatcher to run a new thread and how to make calls back to ProgressBar from Dispatcher

I got this technique from this link:
http://windowsclient.net/learn/video.aspx?v=57027

Its related to using the BackgroundWorker, apparently BackgroundWorker calles Dispatcher, but this example is so simple that I like it.

        private void DoSomething()
        {
                    new Thread(
                      delegate()
                      {
                        Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { progressBar.IsIndeterminate = true; }, null);
                        LongRunningProcess();
                        Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { progressBar.IsIndeterminate = false; }, null);
                      }
                    ).Start();
        }

Tuesday, April 6, 2010

How to use a ProgressBar in WPF using the BackgroundWorker class

- Have a xaml file with a progressBar called "progressBar" and a button called "button".  I called my project ProgressBar.  My window is also called ProgressBar instead of Window1.
- The key parts of the file below are:
    1.  create a BackGroundworker object.
    2.  Add the DoWork and RunWorkerCompleted events to the constructor of your function
    3.  Implement the DoWork event of the background worker
    4.  Implement the RunWorkerCompleted event of the background worker
    5.  Call the RunWorkerAsync function of the background worker.  This calls the DoWork function.  When its done the RunWorkercompleted function is called.  You can have DoWork return you something - in my example its a string but it could be any object.
    6.  You set the progressBar.IsIndeterminate to true in the click event and you set it to false in the Runworkercompleted function
  
That's pretty much it. 
=====================================
using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Windows.Input;

namespace ProgressBar
{
    public partial class ProgressBar : Window
    {
        private BackgroundWorker progressBarWorker;

        public ProgressBar()
        {
            InitializeComponent();

            // Create a Background Worker
            progressBarWorker = new BackgroundWorker();

            // Enable support for cancellation
            progressBarWorker.WorkerSupportsCancellation = true;

            progressBarWorker.DoWork +=
                new DoWorkEventHandler(progressBarWorker_DoWork);
            progressBarWorker.RunWorkerCompleted +=
                new RunWorkerCompletedEventHandler(progressBarWorker_RunWorkerCompleted);
        }

        private void progressBarWorker_RunWorkerCompleted(
            object sender, RunWorkerCompletedEventArgs e)
        {
            this.Cursor = Cursors.Arrow;

            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }

            button.Content = "Start";

            // Reset the ProgressBar's IsInderterminate
            // property to false to stop the progress indicator
            progressBar.IsIndeterminate = false;

          // You can even get a return value from the progressBarWorker using e.result
            string strval = (string)e.Result;
            //do something with strval
            MessageBox.Show(strval);
        }

        private void progressBarWorker_DoWork(
            object sender, DoWorkEventArgs e)
        {
            for (int i = 1; i <= 500; i++)
            {
                if (progressBarWorker.CancellationPending)
                    break;

                Thread.Sleep(50);
            }
            //You can return something from the Worker
            e.Result = "some str";
        }

        private void button_Click(
            object sender, RoutedEventArgs e)
        {
            if (!progressBarWorker.IsBusy)
            {
                this.Cursor = Cursors.Wait;

                // Set the ProgressBar's IsInderterminate
                // property to true to start the progress indicator
                progressBar.IsIndeterminate = true;
                button.Content = "Cancel";

                // Start the Background Worker
                progressBarWorker.RunWorkerAsync();
            }
            else
            {
                progressBarWorker.CancelAsync();
            }
        }

    }
}

Thursday, April 1, 2010

Advantages of routed events

From - http://joshsmithonwpf.wordpress.com/2007/06/22/overview-of-routed-events-in-wpf/

The routed notification pattern has many benefits.  One very important benefit of routed events is that a high-level visual element in a UI need not explicitly hook the same event on all of its descendants, such as MouseMove.  Instead it can hook the event on itself, and when the mouse moves over one of its descendants, the high level element will be notified appropriately.

Another important advantage of routed events is that elements at all levels of the visual tree can execute code in response to events of their descendants, without expecting the descendant to notify them when the event fires.   An ancestor element which hooks a tunneling event can even prevent its descendants from ever receiving both the tunneling and bubbling events at all (although it is possible for an element to demand that it is notified of the event, regardless of it is handled or not).


Call and Raise Events in WPF from Child Control to parent window

I know there are a lot of documentation on routed events in wpf, and examples. For example see http://www.codeproject.com/KB/WPF/BeginWPF3.aspx

Either way, for some reason I just wasn't getting it. It took a couple of hours of reading and trying, but I was finally able to figure it out. Below is my explanation.

Just say you have a MainWindow and in it you have a custom control, called ControlHome. In your ControlHome you want to raise an event and have it caught by the MainWindow. Back in WinForms you would define the event in the control, raise it in the control and then "catch" it in the MainWindow. The idea is somewhat similar in WPF, but you have to do something called Routed Events, and with Routed Events you can do a lot more, but I'll just focus on the scenario of Child Control to MainWindow.

In the Child Control (called ControlHome) you need to create the event
public static RoutedEvent StartProgressBarEvent;
(I've seen a lot of documentation where it was made read-only, but when I did this, I get an error when I define it in the Constructor so I removed the readonly statement.

In the constructor of the child control you register it like this:

StartProgressBarEvent = EventManager.RegisterRoutedEvent("StartProgressBar", RoutingStrategy.Bubble,
typeof(RoutedEventHandler), typeof(ControlHome));

I specified it to "Bubble" which means it goes up the tree. I name "StatusProgressBar" will be used later on. The type is RoutedEventHandler, and ChildControl is the control that is going to raise the event

You also need to add the handler for the Event like this to the child control:
public event RoutedEventHandler StartProgressBar
{
add {base.AddHandler(StartProgressBarEvent, value);}
remove {base.RemoveHandler(StartProgressBarEvent, value);}
}

Lastly when you want to raise the event you can do so like this:
RoutedEventArgs e1 = new RoutedEventArgs(StartProgressBarEvent);
RaiseEvent(e1);

So to review, in the Child Control, you create it, register it and add the handler for it, and raise it when you want to. Now your child control has this event registered to it, so a parent window can just call it. For example, the button has an event called Click, so a parent event can define what will happen when a user clicks on the button.

In the parent window, in the ChildControl.xaml file, where I added the control to the file, I now say that the even StartProgressBar will be handled by the function "StartProgressBar"

<local:ChildControlx:Name="ChildControl1" StartProgressBar="StartProgressBar"/>

In the file ChildControl.xaml.cs, I define the StartProgressBar function, like this:
private void StartProgressBar(object sender, RoutedEventArgs e)
{
// Do something here
}

That's it. The RoutedEvents also allow you to tunnel events down the tree, but I won't get into that right now.

Tuesday, March 30, 2010

OpenFileDialog changes the current directory

I opened a file from my application and later on when I went to run a shell script that was in the application directory, it wasn't able to find the file.  It turns out that the OpenfileDialog changed the current directory and therefore it was looking for my shell script in the new location.  The fixes were:

1.  Change OpenFileDialog to use the RestoreDirectory option and set it to true.  Like this:
            OpenFileDialog fileDlg = new System.Windows.Forms.OpenFileDialog
            {
                Multiselect = MulitFileSelect,
                Filter = "Data Sources (*.txt, *.csv|*.txt*;*.csv|All Files|*.*",
                RestoreDirectory = true
            };
2.   The next thing I did was when I looked for the Shell Script, if it didn't find the file, I inserted code to go to the Application.ExecutablePath and try there.  Keep in mind that ExecutablePath returns the .exe name so you need to call Path.GetDirectoryname on it if you want to get the directory location.


Summary on how to use List in C#

A good summary on how to use the List<> in C#
http://dotnetperls.com/list

Return a List of string and append/concat a List in C#


Got this from stackoverflow - http://stackoverflow.com/questions/1036829/how-to-return-list-of-strings-in-c

public static List<string> GetCities()
{
  List<string> cities = new List<string>();
  cities.Add("Istanbul");
  cities.Add("Athens");
  cities.Add("Sofia");
  return cities;
}

To append to a List just do something like this
List<string> thumbnails = new List<string>();
thumbnails.AddRange(--------have a string array here--------------);


Wednesday, March 24, 2010

Moving a WPF Window with a WindowStyle of None

From: http://cloudstore.blogspot.com/2008/06/moving-wpf-window-with-windowstyle-of.html

To enable a user to move your window from any area on that window (not necessarily just the title if you want to do something really different), you simply handle the MouseLeftButtonDown event for a UIElement on your window and call the DragMove method, as shown in the following code example.

private void title_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DragMove();
}

How to do a redim preserver in C#

This block of code dos the same thing:

string[] nums = {"5", "10", "20"};
string[] temp = new string[10];
System.Array.Copy(nums, 0, temp, 0, nums.Length);
nums = temp;


Monday, March 22, 2010

Three approaches to convert a string to a date in C#

string fileDate = "5/9/2010";
DateTime dt = Convert.ToDateTime(fileDate); //Can be used the same way as ParseExtract below.  It will throw a FormatException exception if it fails.

DateTime dt = DateTime.Parse(fileDate); //will try very hard to generate a DateTime object.  If the string has missing date elements, it will default to the current date and missing time elements default to 12:00:00 am.  After all efforts, if Parse cannot create a DateTime object, it will throw a System.FormatException exception.

DateTime.ParseExact(fileDate, "MMMM dd", null); //You pass a string, a format string the specifies the structure the time and date string must have, and an IFormatProvider reference that provides culture-specific information to the method.  If the IFormatProvider value is null, the current thread's culture information is used.  if it doesn't work, it will throw a System.FormatException exception.



Tuesday, March 16, 2010

IsNumeric in C#

If you need the functionality of IsNumeric in C# and don't want to use the Microsoft.VisualBasic dll then you could use these functions.  I haven't tried them out so can't say how effective they are, just here in case I need something like it in the future.

I found these online.  I can't find the link where I found the one below (my browser just crashed)
using System;
using System.Text;
using System.Text.RegularExpressions;

private bool IsTextValidated(string strTextEntry)
{          
      Regex objNotWholePattern = new Regex("[^0-9]");
      return !objNotWholePattern.IsMatch(strTextEntry)
           && (strTextEntry != "");     
}

http://www.velocityreviews.com/forums/t112796-is-there-any-isnumeric-in-c.html
public static bool IsNumeric(object numberString)
{
char[] ca = numberString.ToString().ToCharArray();
for (int i = 0; i < ca.Length; i++)
{
if (!char.IsNumber(ca[i]))
if (ca[i] != '.')
return false;
}
if (numberString.ToString().Trim() == "")
return false;
return true;
}


Read In Tab Delimited file into Hashtable in C#

    private Hashtable GetHashtableFromFile(string file)
    {
      Hashtable ht = new Hashtable();
      string line = string.Empty;
      using (StreamReader reader = new StreamReader(file))
      {
        int i = 0;
        while ((line = reader.ReadLine()) != null)
        {
          i++;
          string[] args = line.Split(new char[] { ' ' });
          if (args.Length != 2)
          {
            Console.WriteLine("Invalid input string: " + i.ToString());
            continue;
          }
          ht.Add(args[0], args[1]);
          Console.WriteLine("IP:{0}, Site:{1}", args[0], args[1]);
        }
      }

      return ht;

    }

Thursday, March 4, 2010

WIA vs TWAIN

There are many similarities between TWAIN and WIA, but there are also some distinct differences that you should base your choice on when developing an application.

Similarities:

1. As long as a driver exists, both are able to acquire images from devices such as a scanner or camera.  For devices like cameras, sometimes the driver is actually WIA but you can access it via the "TWAIN compatibility layer".
2. Acquire images with a dialog.
3. Programmatically set properties of the device and acquire the images programmatically without showing a dialog
4. Not all capabilities are supported by each device, so you can query the device for the ones that it does support.

Differences:

1. WIA uses a common dialog for all devices while Twain uses a dialog created by the device manufacturer.  Practically speaking, this almost always means that the TWAIN dialog will provide more options and advanced control over the device.
2. TWAIN allows you to use custom capabilities that the device manufacturer has created even though they don't exist in the TWAIN specifications.
3. In general, when a device supports both Twain and WIA, TWAIN is better for scanners and WIA is better for acquiring images from cameras and video devices.
4. TWAIN has three transfer modes (Native, Memory, File) and WIA only has two (Memory, File).
5. Most TWAIN sources save the settings of the previous scan while WIA does not.
6. TWAIN supports options for each page when scanning in duplex mode but WIA uses the same settings for both sides.

For more details on WIA, please visit http://www.microsoft.com/whdc/device/stillimage/WIA-arch.mspx
For more details on TWAIN, please visit http://www.twain.org/

Wednesday, March 3, 2010

Convert.ToBoolean to convert string to boolean

Convert.ToBoolean function can be used to convert strings to boolean
http://msdn.microsoft.com/en-us/library/86hw82a3.aspx


How to access Default Public Property Item in a VB.NET dll from C# code

I have a function in VB.NET that is a Default Public Property Item (...).  So in VB.NET I would access it Something.Item(1) = somevalue, where 1 is the index of the array.  In C# you would access this property via the bracket [].  For example, the above example in C# would be Something[1] = somevalue

Left Pad and Integer in C#

From - http://www.victorchen.info/left-pad-an-integer-with-zeros-in-c/

int myNumber = 234;
string myStringNumber = myNumber.ToString().PadLeft(16, '0');

Tuesday, March 2, 2010

App.config vs registry

1) The built-in code to access an app.config from .NET is very full-featured and easy to use.

2) You can install the application without having to create registry entries.

3) You can remove the install without having to worry about removing registry entries.

4) You don't have to worry about access permissions to the registry (like from Vista).  However, Unprivileged user normally do not have access to the "Program Files" folder or any subfolders, and usually the app.config file will go there.

5) Content in App.config can be protected using RSA Protected configuration providers available in .Net framework

6) App.config is a XML based hirerarical tree structure database which follows standards understod by .Net and which can be accessed like objects by .Net Code unlike registry data.

Monday, March 1, 2010

How to use the app.config file in VS.NET 2008

I know this is straight forward, but for some reason I wasn't able to figure it out at first.  Can't remember what I did wrong, but here is how you can use it:

- Right click on the project and go to Properties.  Click on the settings tab.  In this area start typing in values.  At first there might be a little lag, as the IDE will create a file called app.config, and another one called Settings.settings and Settings.Designer.cs (under the properties folder).  Once you are done you can specify the type of setting, the scope (application, user) and a default value.

The way you access them is such:
Properties.Settings.Default.<Name of Property>.  For example, "Properties.Settings.Default.Username"

The way you set values to this property is such:
Properties.Settings.Default.<Name of Setting> = Value;
Properties.Settings.Default.Save();

That's it. 

I was working in WPF and I wanted to access a setting in the App.xaml.cs file.  However for some reason Properties.Settings wasn't showing up on IntelliSense.  It turns out to be some namespace issue.  In the file app.config my settings are under the following block:
<MainNameSpace.ApplicationName.Properties.Settings> (I changed MainNameSpace and ApplicationName, but your file will have something similar).
The way I was able to access those settings was via:
Noblis.EBTSFileManager.Properties.Settings.Default.<Name of Setting>

Another thing I thought I needed to do was to include the app.config file in the bin directory.  This is not necessary.  The file is copied to the output directory via the application name.  so it will be something like: MainNameSpace.ApplicationName.exe.config.  Ther is also another file there called MainNameSpace.ApplicationName.vshost.exe.config.

More information can be found here:
http://msdn.microsoft.com/en-us/library/a65txexh(VS.80).aspx
http://msdn.microsoft.com/en-us/library/bb397755.aspx

One thing I need to figure out is where is the file with the settings.  For example, I keep a default username in my settings file.  When I run the application, it seems to be loading the values from the file, but the MainNameSpace.ApplicationName.exe.config doesn't have the default username, it looks just like the app.config file.  Where does it go?

Thursday, February 25, 2010

context.xml not installing when using ClickOnce

We had an WPF application and were using ClickOnce to deploy the application.  When we installed the application, we got an error that looked like it could either be on install or startup.  After further investigation we found it was when we started the application.  The specific error I got was a - An unhandled exception (system.TypeInitializationException) occurred in ...  It turned out that the context.xml file that we were using with our application wasn't installed by ClickOnce.  The reason was that we had specified it as an embedded resource.  To fix it, click on the file, and then in the "Build Action" property change it to "Content".  Then right-click on your project and go to properties, and click on the "Publish" tab (I'm using Visual Studio 2008), and click on the "Application Files" button.  In the window that pops up, you should see "context.xml".  In the "Publish Status" column, make sure that you have "Include" selected, and in the "download group" specify "Required" and in the Hash column have "Include".

More information can be found here - http://blogs.msdn.com/karstenj/archive/2006/02/21/536322.aspx

For me this fixed the problem.

Monday, February 22, 2010

How to get a label to wrap in WPF

        <Label Margin="12,8,12,0">
            <TextBlock Text="This is your first time logging in and we need a little more information about you.  Please enter your first, middle, and last name along with your initials in all caps with no spaces or commas (Example PBJ)" TextWrapping="Wrap"  />
        </Label>

Thursday, February 18, 2010

Do the URL's at the top of a XAML file try to access the internet

At the top of a xaml file (after the Window declaration are the two lines below:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

The question came up if these two files cause every WPF application to try to access the Internet.  The answer is a resounding "NO".  What those two lines do is they declare a namespace.  In XML language one uses the term "xmlns" to declare namespaces.  The first line declares a namespace called "http://schemas.microsoft.com/winfx/2006/xaml/presentation" and the second line declares a namespace called "http://schemas.microsoft.com/winfx/2006/xaml".  Its not a pointer to a website, its just a name for a namespace, just like "Ted" is my name.  If I changed my name to "www.ted.com" then that would be my name, not necessarily a pointer to a website.

The difference between the first and second lines is the ":x" that is on the second line.  This basically maps the namespace associated with the second line has a prefix associated with it called "x".  "That means you can use controls in that namespace just by placing the namespace prefix before the element name (as in <x:ElementName>).  Its basically a shortcut to get to a namespace.

The first line doesn't have a prefix, so its the default namespace for the entire file.  This means that if you use a grid control and use the following <Grid>, then the XAML parser will look for that Grid control in the .NET namespaces until it finds System.Windows.Controls.Grid.

The reason its added to the top of every file, is to make sure other companies won't create different XML-based languages with the same namespace. 

Another example is that recently we purchased DevExpress and got their DXGrid control.  The following namespace was declared on some sample code:
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"

Now my understanding is that they have a namespace called "http://schemas.devexpress.com/winfx/2008/xaml/grid" and assigning a prefix called "dxg" to it.  So if I wanted to use their grid, I would do the following <dxg:GridControl ...>.  When I installed their software they installed their GridControl in the namespace "http://schemas.devexpress.com/winfx/2008/xaml/grid", so when the XAML parser runs, it would look on my computer for the namespace "http://schemas.devexpress.com/winfx/2008/xaml/grid" and try to find GridControl.

I hope that makes things clearer.



How to target a specific .NET Version when building an application in Visual Studio

When you create a new project in Visual Studio (by choosing File ➤ New ➤ Project), you can choose the version of the .NET Framework that you're targeting from a drop-down list in the top-right corner of the New Project dialog box (see Figure 1-2). You can also change the version you're targeting at any point afterward by double-clicking the Properties node in the Solution Explorer and changing the selection in the Target Framework list.

WPF Errors - InitializeComponent doesn't exist, etc

I've been learning how to write WPF applications, and I was going through activities in a book.  One of the activities is to create an ImageViewer.

I modified the Window1.xaml file and changed the first line to so that the class is called "ImageViewer.Window1".  I then called a FolderoOpenMenuItem_Click event from the xaml file, and defined it in the Window1.xaml.cs file.  I also had an InitializeComponent in the constructor.  When I compiled the application I got the following errors:

- The name 'InitializeComponent' does not exist in the current context
- 'Windows1.Window1' does not contain a definition for 'FolderOpenMenuItem_Click' and no extension method for 'FolderOpenMenuItem_Click' accepting a first argument of type 'Window1.Window1' could be found (are you missing a using directive or an assembly reference?)

This didn't make sense to me because I had defined the function, so why was it saying that nothing existed.  Also, I didn't know where the InitializeComponent function was defined.

After looking on the web, I found the following link - http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/2f755d30-bd8c-4f9b-b36a-9cb56bea15cd

Basically the issue is that in the obj\Debug folder is a file Window1.g.cs and here is where InitializeComponent is defined.  The namespace I had was wrong, and once I changed the namespace to ImageViewer everything was able to build and work.

However, I was still concerned that if I changed the build configuration to release there would be problems.  But when I did so there were no problems.  But I still didn't like this solution, so what I did was right-click on the project and changed the Assembly Name and Default Namespace to ImageViewer and did a global replace for the solution on anything that said WPFapplication1 to ImageViewer.  I was able to build it and everything seemds to now work.
 

Thursday, January 21, 2010

TFS Icons not showing up in solution explorer

This document deals with the issue where you've added your solution to TFS, but the TFS icons are not showing up in solution explorer therefore appearing like the project isn't under source control.
 
You've already tried to go to Tools->Options->Source Control->Plug-in Selection, and selected "Visual Studio Team Foundation Server".  But still it appears like its not under source control.
Click on File-->Source Control-->Change Source Control.  In the Change Source Control dialog, check the server bindings to ensure they are setup correctly.  If there are issues with the bindings, you will see red squiggly lines under the server names - or - if there are no bindings at all, you will see "<No Server>" in the Server Name/Binding columns.
If you see "<No Server> click on the "Bind" button.  If you've already added the project to source control then it will automatically bind them.  At this point it will ask you to check out the Solution and Project file, do so and then check it back in.  You should now be set.
If you see issues in this dialog, you can unbind each of the projects by selecting the project and clicking the "Unbind" toolbar button.  Once you've unbound the projects, you can rebind them by selecting each project and clicking "Bind".
If you still have issues, you might need to reinstall VS and see if it works.