Archive

Posts Tagged ‘C#’

Don’t Write WPF Converters; Write C# Inline In Your XAML Instead Using QuickConverter

December 13th, 2013 7 comments

If you’ve used binding at all in WPF then you more then likely have also written a converter.  There are lots of tutorials on creating converters, so I’m not going to discuss that in length here.  Instead I want to spread the word about a little known gem called QuickConverter.  QuickConverter is awesome because it allows you to write C# code directly in your XAML; this means no need for creating an explicit converter class.  And it’s available on NuGet so it’s a snap to get it into your project.

 

A simple inverse boolean converter example

As a simple example, let’s do an inverse boolean converter; something that is so basic I’m surprised that it is still not included out of the box with Visual Studio (and why packages like WPF Converters exist).  So basically if the property we are binding to is true, we want it to return false, and if it’s false, we want it to return true.

The traditional approach

This post shows the code for how you would traditionally accomplish this.  Basically you:

1) add a new file to your project to hold your new converter class,

2) have the class implement IValueConverter,

3) add the class as a resource in your xaml file, and then finally

4) use it in the Converter property of the xaml control.  Man, that is a lot of work to flip a bit!

Just for reference, this is what step 4 might look like in the xaml:

<CheckBox IsEnabled="{Binding Path=ViewModel.SomeBooleanProperty, Converter={StaticResource InverseBooleanConverter}" />

 

Using QuickConverter

This is what you would do using QuickConverter:

<CheckBox IsEnabled="{qc:Binding '!$P', P={Binding Path=ViewModel.SomeBooleanProperty}}" />

That it! 1 step! How freaking cool is that!  Basically we bind our SomeBooleanProperty to the variable $P, and then write our C# expressions against $P, all in xaml! This also allows us to skip steps 1, 2, and 3 of the traditional approach, allowing you to get more done.

 

More examples using QuickConverter

The QuickConverter documentation page shows many more examples, such as a Visibility converter:

Visibility="{qc:Binding '$P ? Visibility.Visible : Visibility.Collapsed', P={Binding ShowElement}}"

 

Doing a null check:

IsEnabled="{qc:Binding '$P != null', P={Binding Path=SomeProperty}"

 

Checking a class instance’s property values:

IsEnabled="{qc:Binding '$P.IsValid || $P.ForceAlways', P={Binding Path=SomeClassInstance}"

 

Doing two-way binding:

Height="{qc:Binding '$P * 10', ConvertBack='$value * 0.1', P={Binding TestWidth, Mode=TwoWay}}"

 

Doing Multi-binding:

Angle="{qc:MultiBinding 'Math.Atan2($P0, $P1) * 180 / 3.14159', P0={Binding ActualHeight, ElementName=rootElement}, P1={Binding ActualWidth, ElementName=rootElement}}"

 

Declaring and using local variables in your converter expression:

IsEnabled="{qc:Binding '(Loc = $P.Value, A = $P.Show) => $Loc != null &amp;&amp; $A', P={Binding Obj}}"

* Note that the "&&" operator must be written as "&amp;&amp;" in XML.

 

And there is even limited support for using lambdas, which allows LINQ to be used:

ItemsSource="{qc:Binding '$P.Where(( (int)i ) => (bool)($i % 2 == 0))', P={Binding Source}}"

 

Quick Converter Setup

As mentioned above, Quick Converter is available via NuGet.  Once you have it installed in your project, there are 2 things you need to do:

1. Register assemblies for the types that you plan to use in your quick converters

For example, if you want to use the Visibility converter shown above, you need to register the System.Windows assembly, since that is where the System.Windows.Visibility enum being referenced lives.  You can register the System.Windows assembly with QuickConverter using this line:

QuickConverter.EquationTokenizer.AddNamespace(typeof(System.Windows.Visibility));

In order to avoid a XamlParseException at run-time, this line needs to be executed before the quick converter executes.  To make this easy, I just register all of the assemblies with QuickConverter in my application’s constructor.  That way I know they have been registered before any quick converter expressions are evaluated.

So my App.xaml.cs file contains this:

public partial class App : Application
{
	public App() : base()
	{
		// Setup Quick Converter.
		QuickConverter.EquationTokenizer.AddNamespace(typeof(object));
		QuickConverter.EquationTokenizer.AddNamespace(typeof(System.Windows.Visibility));
	}
}

Here I also registered the System assembly (using “typeof(object)”) in order to make the primitive types (like bool) available.

 

2. Add the QuickConverter namespace to your Xaml files

As with all controls in xaml, before you can use a you a control you must create a reference to the namespace that the control is in.  So to be able to access and use QuickConverter in your xaml file, you must include it’s namespace, which can be done using:

xmlns:qc="clr-namespace:QuickConverter;assembly=QuickConverter"

 

So should I go delete all my existing converters?

As crazy awesome as QuickConverter is, it’s not a complete replacement for converters.  Here are a few scenarios where you would likely want to stick with traditional converters:

1. You need some very complex logic that is simply easier to write using a traditional converter.  For example, we have some converters that access our application cache and lock resources and do a lot of other logic, where it would be tough (impossible?) to write all of that logic inline with QuickConverter.  Also, by writing it using the traditional approach you get things like VS intellisense and compile-time error checking.

2. If the converter logic that you are writing is very complex, you may want it enclosed in a converter class to make it more easily reusable; this allows for a single reusable object and avoids copy-pasting complex logic all over the place.  Perhaps the first time you write it you might do it as a QuickConverter, but if you find yourself copy-pasting that complex logic a lot, move it into a traditional converter.

3. If you need to debug your converter, that can’t be done with QuickConverter (yet?).

 

Summary

So QuickConverter is super useful and can help speed up development time by allowing most, if not all, of your converters to be written inline.  In my experience 95% of converters are doing very simple things (null checks, to strings, adapting one value type to another, etc.), which are easy to implement inline.  This means fewer files and classes cluttering up your projects.  If you need to do complex logic or debug your converters though, then you may want to use traditional converters for those few cases.

So, writing C# inline in your xaml; how cool is that!  I can’t believe Microsoft didn’t think of and implement this.  One of the hardest things to believe is that Johannes Moersch came up with this idea and implemented it while on a co-op work term in my office!  A CO-OP STUDENT WROTE QUICKCONVERTER!  Obviously Johannes is a very smart guy, and he’s no longer a co-op student; he’ll be finishing up his bachelor’s degree in the coming months.

I hope you find QuickConverter as helpful as I have, and if you have any suggestions for improvements, be sure to leave Johannes a comment on the CodePlex page.

Happy coding!

Categories: C#, WPF, XAML Tags: , , , , , , ,

Creating Strongly Typed Objects In PowerShell, Rather Than Using An Array Or PSCustomObject

October 21st, 2013 1 comment

I recently read a great article that explained how to create hashtables, dictionaries, and PowerShell objects.  I already knew a bit about these, but this article gives a great comparison between them, when to use each of them, and how to create them in the different versions of PowerShell.

Right now I’m working on refactoring some existing code into some general functions for creating, removing, and destroying IIS applications (read about it here).  At first, I thought that this would be a great place to use PSCustomObject, as in order to perform these operations I needed 3 pieces of information about a website; the Website name, the Application Name (essentially the path to the application under the Website root), and the Application Pool that the application should run in.

 

Using an array

So initially the code I wrote just used an array to hold the 3 properties of each application service:

# Store app service info as an array of arrays.
$AppServices = @(
	("MyWebsite", "$Version/Reporting.Services", "Services .NET4"),
	("MyWebsite", "$Version/Core.Services", "Services .NET4"),
	...
)

# Remove all of the Web Applications.
foreach ($appInfo in $AppServices )
{
	$website = $appInfo[0]
	$appName = $appInfo[1]
	$appPool = $appInfo[2]
	...
}

There is nothing “wrong” with using an array to store the properties; it works.  However, now that I am refactoring the functions to make them general purpose to be used by other people/scripts,  this does have one very undesirable limitation; The properties must always be stored in the correct order in the array (i.e. Website in position 0, App Name in 1, and App Pool in 2).  Since the list of app services will be passed into my functions, this would require the calling script to know to put the properties in this order.  Boo.

Another option that I didn’t consider when I originally wrote the script was to use an associative array, but it has the same drawbacks as using a PSCustomObject discussed below.

 

Using PSCustomObject

So I thought let’s use a PSCustomObject instead, as that way the client does not have to worry about the order of the information; as long as their PSCustomObject has Website, ApplicationPath, and ApplicationPool properties then we’ll be able to process it.  So I had this:

[PSCustomObject[]] $applicationServicesInfo = @(
	[PSCustomObject]@{Website = "MyWebsite"; ApplicationPath = "$Version/Reporting.Services"; ApplicationPool = "Services .NET4"},
	[PSCustomObject]@{Website = "MyWebsite"; ApplicationPath = "$Version/Core.Services"; ApplicationPool = "Services .NET4},
	...
)

function Remove-ApplicationServices
{
	param([PSCustomObject[]] $ApplicationServicesInfo)

	# Remove all of the Web Applications.
	foreach ($appInfo in [PSCustomObject[]]$ApplicationServicesInfo)
	{
		$website = $appInfo.Website
		$appPath = $appInfo.ApplicationPath
		$appPool = $appInfo.ApplicationPool
		...
	}
}

I liked this better as the properties are explicitly named, so there’s no guess work about which information the property contains, but it’s still not great.  One thing that I don’t have here (and really should), is validation to make sure that the passed in PSCustomObjects actually have Website, ApplicationPath, and ApplicationPool properties on them, otherwise an exception will be thrown when I try to access them.  So with this approach I would still need to have documentation and validation to ensure that the client passes in a PSCustomObject with those properties.

 

Using a new strongly typed object

I frequently read other PowerShell blog posts and recently stumbled across this one.  In the article he mentions creating a new compiled type by passing a string to the Add-Type cmdlet; essentially writing C# code in his PowerShell script to create a new class.  I knew that you could use Add-Type to import other assemblies, but never realized that you could use it to import an assembly that doesn’t actually exist (i.e. a string in your PowerShell script).  This is freaking amazing! So here is what my new solution looks like:

try {	# Wrap in a try-catch in case we try to add this type twice.
# Create a class to hold an IIS Application Service's Information.
Add-Type -TypeDefinition @"
	using System;
	
	public class ApplicationServiceInformation
	{
		// The name of the Website in IIS.
		public string Website { get; set;}
		
		// The path to the Application, relative to the Website root.
		public string ApplicationPath { get; set; }

		// The Application Pool that the application is running in.
		public string ApplicationPool { get; set; }

		// Implicit Constructor.
		public ApplicationServiceInformation() { }

		// Explicit constructor.
		public ApplicationServiceInformation(string website, string applicationPath, string applicationPool)
		{
			this.Website = website;
			this.ApplicationPath = applicationPath;
			this.ApplicationPool = applicationPool;
		}
	}
"@
} catch {}

$anotherService = New-Object ApplicationServiceInformation
$anotherService.Website = "MyWebsite"
$anotherService.ApplicationPath = "$Version/Payment.Services"
$anotherService.ApplicationPool = "Services .NET4"
	
[ApplicationServiceInformation[]] $applicationServicesInfo = @(
	(New-Object ApplicationServiceInformation("MyWebsite", "$Version/Reporting.Services", "Services .NET4")),
	(New-Object ApplicationServiceInformation -Property @{Website = "MyWebsite"; ApplicationPath = "$Version/Core.Services"; ApplicationPool = "Services .NET4}),
	$anotherService,
	...
)

function Remove-ApplicationServices
{
	param([ApplicationServiceInformation[]] $ApplicationServicesInfo)

	# Remove all of the Web Applications.
	foreach ($appInfo in [ApplicationServiceInformation[]]$ApplicationServicesInfo)
	{
		$website = $appInfo.Website
		$appPath = $appInfo.ApplicationPath
		$appPool = $appInfo.ApplicationPool
		...
	}
}

I first create a simple container class to hold the application service information, and now all of my properties are explicit like with the PSCustomObject, but also I’m guaranteed the properties will exist on the object that is passed into my function.  From there I declare my array of ApplicationServiceInformation objects, and the function that we can pass them into. Note that I wrap each New-Object call in parenthesis, otherwise PowerShell parses it incorrectly and will throw an error.

As you can see from the snippets above and below, there are several different ways that we can initialize a new instance of our ApplicationServiceInformation class:

$service1 = New-Object ApplicationServiceInformation("Explicit Constructor", "Core.Services", ".NET4")

$service2 = New-Object ApplicationServiceInformation -ArgumentList ("Explicit Constructor ArgumentList", "Core.Services", ".NET4")

$service3 = New-Object ApplicationServiceInformation -Property @{Website = "Using Property"; ApplicationPath = "Core.Services"; ApplicationPool = ".NET4"}

$service4 = New-Object ApplicationServiceInformation
$service4.Website = "Properties added individually"
$service4.ApplicationPath = "Core.Services"
$service4.ApplicationPool = "Services .NET4"

 

Caveats

  • Note that I wrapped the call to Add-Type in a Try-Catch block.  This is to prevent PowerShell from throwing an error if the type tries to get added twice.  It’s sort of a hacky workaround, but there aren’t many good alternatives, since you cannot unload an assembly.
  • This means that while developing if you make any changes to the class, you’ll have to restart your PowerShell session for the changes to be applied, since the Add-Type cmdlet will only work properly the first time that it is called in a session.

I hope you found something in here useful.

Happy coding!

Adding and accessing custom sections in your C# App.config

September 25th, 2012 34 comments

Update (Feb 10, 2016): I found a NuGet package called simple-config that allows you to dynamically bind a section in your web/app.config file to a strongly typed class without having to write all of the boiler-plate code that I show here. This may be an easier solution for you than going through the code I show below in this post.

So I recently thought I’d try using the app.config file to specify some data for my application (such as URLs) rather than hard-coding it into my app, which would require a recompile and redeploy of my app if one of our URLs changed.  By using the app.config it allows a user to just open up the .config file that sits beside their .exe file and edit the URLs right there and then re-run the app; no recompiling, no redeployment necessary.

I spent a good few hours fighting with the app.config and looking at examples on Google before I was able to get things to work properly.  Most of the examples I found showed you how to pull a value from the app.config if you knew the specific key of the element you wanted to retrieve, but it took me a while to find a way to simply loop through all elements in a section, so I thought I would share my solutions here.

Due to the popularity of this post, I have created a sample solution that shows the full implementation of both of the methods mentioned below.

Simple and Easy

The easiest way to use the app.config is to use the built-in types, such as NameValueSectionHandler.  For example, if we just wanted to add a list of database server urls to use in my app, we could do this in the app.config file like so:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="ConnectionManagerDatabaseServers" type="System.Configuration.NameValueSectionHandler" />
    </configSections>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <ConnectionManagerDatabaseServers>
        <add key="localhost" value="localhost" />
        <add key="Dev" value="Dev.MyDomain.local" />
        <add key="Test" value="Test.MyDomain.local" />
        <add key="Live" value="Prod.MyDomain.com" />
    </ConnectionManagerDatabaseServers>
</configuration>

And then you can access these values in code like so:

string devUrl = string.Empty;
var connectionManagerDatabaseServers = ConfigurationManager.GetSection("ConnectionManagerDatabaseServers") as NameValueCollection;
if (connectionManagerDatabaseServers != null)
{
    devUrl = connectionManagerDatabaseServers["Dev"].ToString();
}

Sometimes though you don’t know what the keys are going to be and you just want to grab all of the values in that ConnectionManagerDatabaseServers section.  In that case you can get them all like this:

// Grab the Environments listed in the App.config and add them to our list.
var connectionManagerDatabaseServers = ConfigurationManager.GetSection("ConnectionManagerDatabaseServers") as NameValueCollection;
if (connectionManagerDatabaseServers != null)
{
    foreach (var serverKey in connectionManagerDatabaseServers.AllKeys)
    {
        string serverValue = connectionManagerDatabaseServers.GetValues(serverKey).FirstOrDefault();
        AddDatabaseServer(serverValue);
    }
}

And here we just assume that the AddDatabaseServer() function adds the given string to some list of strings.

One thing to note is that in the app.config file, <configSections> must be the first thing to appear in the <configuration> section, otherwise an error will be thrown at runtime. Also, the ConfigurationManager class is in the System.Configuration namespace, so be sure you have

using System.Configuration

at the top of your C# files, as well as the “System.Configuration” assembly included in your project’s references.

So this works great, but what about when we want to bring in more values than just a single string (or technically you could use this to bring in 2 strings, where the “key” could be the other string you want to store; for example, we could have stored the value of the Key as the user-friendly name of the url).

More Advanced (and more complicated)

So if you want to bring in more information than a string or two per object in the section, then you can no longer simply use the built-in System.Configuration.NameValueSectionHandler type provided for us.  Instead you have to build your own types.  Here let’s assume that we again want to configure a set of addresses (i.e. urls), but we want to specify some extra info with them, such as the user-friendly name, if they require SSL or not, and a list of security groups that are allowed to save changes made to these endpoints.

So let’s start by looking at the app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="ConnectionManagerDataSection" type="ConnectionManagerUpdater.Data.Configuration.ConnectionManagerDataSection, ConnectionManagerUpdater" />
    </configSections>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
    <ConnectionManagerDataSection>
        <ConnectionManagerEndpoints>
            <add name="Development" address="Dev.MyDomain.local" useSSL="false" />
            <add name="Test" address="Test.MyDomain.local" useSSL="true" />
            <add name="Live" address="Prod.MyDomain.com" useSSL="true" securityGroupsAllowedToSaveChanges="ConnectionManagerUsers" />
        </ConnectionManagerEndpoints>
    </ConnectionManagerDataSection>
</configuration>

The first thing to notice here is that my section is now using the type “ConnectionManagerUpdater.Data.Configuration.ConnectionManagerDataSection” (the fully qualified path to my new class I created) “, ConnectionManagerUpdater” (the name of the assembly my new class is in).  Next, you will also notice an extra layer down in the <ConnectionManagerDataSection> which is the <ConnectionManagerEndpoints> element.  This is a new collection class that I created to hold each of the Endpoint entries that are defined.  Let’s look at that code now:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConnectionManagerUpdater.Data.Configuration
{
    public class ConnectionManagerDataSection : ConfigurationSection
    {
        /// <summary>
        /// The name of this section in the app.config.
        /// </summary>
        public const string SectionName = "ConnectionManagerDataSection";

        private const string EndpointCollectionName = "ConnectionManagerEndpoints";

        [ConfigurationProperty(EndpointCollectionName)]
        [ConfigurationCollection(typeof(ConnectionManagerEndpointsCollection), AddItemName = "add")]
        public ConnectionManagerEndpointsCollection ConnectionManagerEndpoints { get { return (ConnectionManagerEndpointsCollection)base[EndpointCollectionName]; } }
    }

    public class ConnectionManagerEndpointsCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new ConnectionManagerEndpointElement();
        }

        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((ConnectionManagerEndpointElement)element).Name;
        }
    }

    public class ConnectionManagerEndpointElement : ConfigurationElement
    {
        [ConfigurationProperty("name", IsRequired = true)]
        public string Name
        {
            get { return (string)this["name"]; }
            set { this["name"] = value; }
        }

        [ConfigurationProperty("address", IsRequired = true)]
        public string Address
        {
            get { return (string)this["address"]; }
            set { this["address"] = value; }
        }

        [ConfigurationProperty("useSSL", IsRequired = false, DefaultValue = false)]
        public bool UseSSL
        {
            get { return (bool)this["useSSL"]; }
            set { this["useSSL"] = value; }
        }

        [ConfigurationProperty("securityGroupsAllowedToSaveChanges", IsRequired = false)]
        public string SecurityGroupsAllowedToSaveChanges
        {
            get { return (string)this["securityGroupsAllowedToSaveChanges"]; }
            set { this["securityGroupsAllowedToSaveChanges"] = value; }
        }
    }
}

So here the first class we declare is the one that appears in the <configSections> element of the app.config.  It is ConnectionManagerDataSection and it inherits from the necessary System.Configuration.ConfigurationSection class.  This class just has one property (other than the expected section name), that basically just says I have a Collection property, which is actually a ConnectionManagerEndpointsCollection, which is the next class defined.

The ConnectionManagerEndpointsCollection class inherits from ConfigurationElementCollection and overrides the required fields.  The first tells it what type of Element to create when adding a new one (in our case a ConnectionManagerEndpointElement), and a function specifying what property on our ConnectionManagerEndpointElement class is the unique key, which I’ve specified to be the Name field.

The last class defined is the actual meat of our elements.  It inherits from ConfigurationElement and specifies the properties of the element (which can then be set in the xml of the App.config).  The “ConfigurationProperty” attribute on each of the properties tells what we expect the name of the property to correspond to in each element in the app.config, as well as some additional information such as if that property is required and what it’s default value should be.

Finally, the code to actually access these values would look like this:

// Grab the Environments listed in the App.config and add them to our list.
var connectionManagerDataSection = ConfigurationManager.GetSection(ConnectionManagerDataSection.SectionName) as ConnectionManagerDataSection;
if (connectionManagerDataSection != null)
{
    foreach (ConnectionManagerEndpointElement endpointElement in connectionManagerDataSection.ConnectionManagerEndpoints)
    {
        var endpoint = new ConnectionManagerEndpoint() { Name = endpointElement.Name, ServerInfo = new ConnectionManagerServerInfo() { Address = endpointElement.Address, UseSSL = endpointElement.UseSSL, SecurityGroupsAllowedToSaveChanges = endpointElement.SecurityGroupsAllowedToSaveChanges.Split(',').Where(e => !string.IsNullOrWhiteSpace(e)).ToList() } };
        AddEndpoint(endpoint);
    }
}

This looks very similar to what we had before in the “simple” example.  The main points of interest are that we cast the section as ConnectionManagerDataSection (which is the class we defined for our section) and then iterate over the endpoints collection using the ConnectionManagerEndpoints property we created in the ConnectionManagerDataSection class.

Also, some other helpful resources around using app.config that I found (and for parts that I didn’t really explain in this article) are:

How do you use sections in C# 4.0 app.config? (Stack Overflow) <== Shows how to use Section Groups as well, which is something that I did not cover here, but might be of interest to you.

How to: Create Custom Configuration Sections Using Configuration Section (MSDN)

ConfigurationSection Class (MSDN)

ConfigurationCollectionAttribute Class (MSDN)

ConfigurationElementCollection Class (MSDN)

I hope you find this helpful.  Feel free to leave a comment.  Happy Coding!

Categories: .NET, C# Tags: , , , ,

Sweet C# Gems

September 2nd, 2011 No comments

James Michael Hare has a lot of awesome C# and .Net related posts, so this is just a little shout out to him (and my own little way of bookmarking his blogs since GWB doesn’t provide a way to "favourite" or "follow" him).  Of particular awesomeness is his C#/.NET Little Wonders and Pitfalls series, and the C#/.NET Fundamentals: Choosing the Right Collection Class.  Keep the great posts coming James!

Categories: .NET, C# Tags: ,

Adding ValueChanged events to Dependency Objects in WPF

April 17th, 2011 No comments

You may be wondering which is the best way to hookup a DependencyProperty’s Callback event handler to handle Value Changed events.  The two methods to consider are:

Method 1 – Use static event hanlders, like so:

public virtual int SelectedID
{
	get { return (int)GetValue(SelectedIDProperty); }
	set { SetValue(SelectedIDProperty, value); }
}

public static readonly DependencyProperty SelectedIDProperty =
	DependencyProperty.Register("SelectedID", typeof(int), typeof(SelectorBase), 
                new PropertyMetadata(0, new PropertyChangedCallback(OnSelectedIDChanged)));

private static void OnSelectedIDChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
	// Perform event handler logic
}

 

Method 2 – Hookup event handler at initialize, and remove it during Dispose(), like so:

// Constructor
public SelectorBase()
{
	HookupEventHandlers();
}

private void HookupEventHandlers()
{
	TypeDescriptor.GetProperties(this)["SelectedID"].AddValueChanged(this, SelectedID_ValueChanged);
}

private void RemoveEventHandlers()
{
	TypeDescriptor.GetProperties(this)["SelectedID"].RemoveValueChanged(this, SelectedID_ValueChanged);
}

protected override void Dispose(bool isDisposing)
{
	base.Dispose(isDisposing);
	// If managed resources should be released
	if (isDisposing)
	{
		RemoveEventHandlers();
	}
}

public virtual int SelectedID
{
	get { return (int)GetValue(SelectedIDProperty); }
	set { SetValue(SelectedIDProperty, value); }
}

public static readonly DependencyProperty SelectedIDProperty =
	DependencyProperty.Register("SelectedID", typeof(int), typeof(SelectorBase), new PropertyMetadata(0));

private void SelectedID_ValueChanged(object sender, EventArgs e)
{
	// Perform event handler logic
}

So the advantage to using method 1 is that we have access to the property’s old and new values, we don’t have to worry about memory leaks (since the event handler is static), and if we create 100 instances of the control we still only have one static event handler in memory, instead of 100 local ones.  The disadvantage to method 1 is that these event handlers are going to exist in memory for the entire lifetime of the app, even if the view/control they are on is never referenced.

The advantage to using method 2 is that the event handlers only exist in memory if the view/control they are on is actually open.  The disadvantage is that we don’t have access to the property’s old value, and the developer has to remember to properly unhook the event in order to avoid a memory leak.

So method 1 is best suited to items that are used in many places (such as custom controls that may be plastered all of the place), while method 2 is best suited for views where there is likely to never be more than a few instances open at any given time, or in places that may not be accessed at all (e.g. a settings menu that is rarely accessed).

My WPF Binding won’t work. WTF!

April 17th, 2011 No comments

At one point or another I’m sure we’ve all been confused as to why our binding won’t work.  Here’s a couple things to keep in mind:

– have you set the DataContext to be the class containing the property you are binding to?  This can be done in XAML or in the code-behind.  For example, put "this.DataContext = this" in the code-behind file’s constructor.

– is the property you’re binding to public?  Also, it must be a property (with get; set; accessors), not a field (i.e. class variable).

– if you are using two way binding, do you have both a Get and Set accessor on the propery?

– if you are trying to set bindings on a usercontrol that you are placing on your form, you may have to set the DataContext in that control, or reference the property dynamically using something like:

<controls:CashCalculator

  CanModifyAmount="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:WpfViewBase}},

Path=CashOutViewModel.CanModifyAmount, Mode=OneWay}"

  CashDetail="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:WpfViewBase}},

Path=CashOutViewModel.CashOutModel.CashOut.CashDetail, Mode=OneWay}"/>

If you still don’t know why your binding isn’t working, be sure to check the Output window in Visual Studio while debugging, as it will display any binding errors that occur and (hopefully) give you more information about the problem.  You can also change the level of verbosity that is displayed for Binding errors, so if you aren’t getting enough information, in Visual Studio go into Tools -> Options -> Debugging -> Output Window and make sure Data Binding is at least set to Warning.

If changes made to the UI propogate to the code-behind, but changes made in the code-behind don’t propogate to the UI, you will either need to use the INotifyPropertyChanged pattern, or implement your code-behind properties as DependencyProperties, in order to let the UI know that the value has been updated and show the change.

Categories: Binding, WPF Tags: , , ,

Setting focus to an element in WPF

April 17th, 2011 No comments

So if you are trying to set focus to a WPF element, but are unable to.  Here is a quick checklist to go through:

– is the control you are trying to set focus to Enabled, Visible, Loaded, and Focusable.  If any of these properties are false, you cannot set focus to the element.

If you are using Binding to set these properties, make sure the binding is firing before you are trying to set the focus.

– does the control that already has focus allow focus to be taken away? If the control that currently has focus overrides the PreviewLostFocus event, it can set e.Handled to true to prevent other controls from stealing focus from it.

If all of these conditions seem to be met, but you still cannot seem to set the focus to a control, is another operation moving focus from your control to another control after you set focus to your control?  From a dispatcher perhaps?

Using the tool Snoop is great for viewing what control in your WPF application has focus, and is very useful in debugging for seeing what controls are recieving focus.  Once you know what control is getting focus instead of your control, you can put a breakpoint in the control’s GotFocus event to debug and see when focus is being moved to the control, and what fuction is performing the operation to move the focus.

Categories: WPF Tags: , , , ,

Some Visual Studio 2010 Shortcuts and C# 4.0 Cool Stuff

April 17th, 2011 1 comment

A list of some shortcus and new features to VS 2010 and C# 4.0:

  • Default values for parameters
  • Can access parameters by name (i.e. SomeFunction(name: "Dan", age: 26);
  • Can now put Labels on breakpoints and filter the breakpoints, as well as import and export breakpoints.
  • Window => New Window to open up same file in two separate tabs, or can drag the splitter at the top-right corner of the edit window.
  • Edit => Outlining => Hide Selection to collapse any region of code
  • Alt + Mouse Left Drag for box selection instead of line selection, then just start typing; you can also use Alt+Shift+Arrow Keys to do box selection with the keyboard.
  • Alt+Arrow Keys to move current line up/down.  Can also select multiple lines and use Alt+Up/Down to move the whole selection up/down.
  • In NavigateTo search window (Ctrl + Comma) use capitals to search for camel casing (i.e. CE to find displayCustomerEmails) and a space to do an "and" search (i.e. "email customer" would find displayCustomerEmails).
  • Ctrl + I to do an incremental search of a document, then F3 and Shift + F3 to move to next/previous matches.
  • Use snippets to automatically create code and save time.
  • Ctrl + Period to access VS tickler window instead of having to hover over the variable with the mouse.
  • Ctrl + Alt + Spacebar to change VS to suggest variable names instead of auto completing them.
  • Can right click in document to remove and sort using statements.
  • Enum.TryParse() has been added to match a string or number to an enumerated type.
  • Contract.Requires() and .Ensures() to ensure that function conditions are met (at compile time).
  • String.IsNullOrWhitespace(string);
  • Lazy<T> for thread-safe lazy loading of variables.
  • VS => Options => Debugging => Output Window => Data Binding to give more info about errors.
  • Using System.Threading.Tasks for parallel processing.  Parallel.For() and .ForEach
  • PLINQ => myCollection.InParallel().Where(x => …..);
  • New Dynamic keyword type => just like Object except not checked at compile time.
  • Ctrl+Shift+V to cycle through clipboard ring
  • Alt+Ctrl+Down to access tab menu
  • Ctrl+Shift+Up/Down to move between instances of the highlighted variable
  • Ctrl+] to move back and forth between a functions opening and closing braces (i.e. "{" and "}"). This appears to also work in XAML!
  • Alt+Arrow Keys to move current line up/down.  Can also select multiple lines and use Alt+Up/Down to move the whole selection up/down.
  • Rather than selecting a whole line first, just use Ctrl+C or Ctrl+X to Copy/Cut the entire line. You can also use Shift+Delete to delete an entire line without selecting it.