<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Chris Holmes Online &#187; Software Development</title>
	<atom:link href="http://www.chrisholmesonline.com/categories/software-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.chrisholmesonline.com</link>
	<description>Adventures in .NET &#38; Agile Development...</description>
	<lastBuildDate>Mon, 28 Nov 2011 00:52:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Silverlight RIA Services with POCO &amp; Oracle: Part 2</title>
		<link>http://www.chrisholmesonline.com/2011/01/19/silverlight-ria-services-with-poco-oracle-part-2/</link>
		<comments>http://www.chrisholmesonline.com/2011/01/19/silverlight-ria-services-with-poco-oracle-part-2/#comments</comments>
		<pubDate>Wed, 19 Jan 2011 19:29:34 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ALT.NET]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Work Related]]></category>

		<guid isPermaLink="false">http://www.chrisholmesonline.com/?p=567</guid>
		<description><![CDATA[You can read Part Ihere. In the last post I gave an overview of the sample Silverlight + RIA application (code can be found here). For Part 2, I wanted to talk more about the specifics of the service layer and the order of the calls. You&#8217;ll notice the declaration of several data sources in [...]]]></description>
			<content:encoded><![CDATA[<p>You can read Part I<a href="http://www.chrisholmesonline.com/2011/01/13/silverlight-ria-services-with-poco-oracle-part-i/">here</a>.</p>
<p>In the last post I gave an overview of the <a href="http://www.chrisholmesonline.com/SilverlightAggregate.zip">sample Silverlight + RIA application </a> (code can be found <a href="http://www.chrisholmesonline.com/SilverlightAggregate.zip">here</a>). For Part 2, I wanted to talk more about the specifics of the service layer and the order of the calls. </p>
<p>You&#8217;ll notice the declaration of several data sources in the constructor of the service: </p>
<pre name="code" class="c-sharp">
[EnableClientAccess()]
  public class TicketService : DomainService
  {
    private TicketDataSource _ticketDataSource;
    private CustomerDataSource _customerDataSource;
    private ProductDataSource _productDataSource;
    private ActionTypeDataSource _actionTypeDataSource;
    private ResultTypeDataSource _resultTypeDataSource;
    private TicketActionDataSource _ticketActionDataSource;

    public TicketService()
    {
      _ticketDataSource = new TicketDataSource();
      _customerDataSource = new CustomerDataSource();
      _productDataSource = new ProductDataSource();
      _actionTypeDataSource = new ActionTypeDataSource();
      _resultTypeDataSource = new ResultTypeDataSource();
      _ticketActionDataSource = new TicketActionDataSource();
    }
</pre>
<p>In our production environment we&#8217;re delegating the actual database operations to separate classes that make calls to Oracle Stored Procedures through ADO.NET using an Oracle provider. It doesn&#8217;t have to be an Oracle DB of course &#8211; you could use any database you like when you just want to hide the details away behind an abstraction such as this. For the sample application, we store the data in memory using the HTTP Session. </p>
<p><strong>Insert: Order Of Operations</strong></p>
<p>What I really wanted to talk about in this post is the order of operations when it comes to doing inserts and saving new entities. For this application we have three pieces of data that can be inserted into the database:</p>
<ul>
<li>Ticket</li>
<li>Customer</li>
<li>TicketAction</li>
</ul>
<p>Product, ActionType and ResultType are also data on the Ticket or TicketAction objects, but they are pulled from the database tables as static lookups and only referenced in their parent objects as foreign keys. No new values are inserted into these three tables via the application and that is why they do not have INSERT methods on the TicketService. </p>
<p>Ticket is our root aggregate object. Customer is a child object on the root, and TicketActions are a collection on the root. The order of operations is determined by RIA. InsertCustomer() will be called first, then InsertTicket() and finally, InsertTicketAction(). Let&#8217;s see how and why this happens. </p>
<p><strong>Inserting a Customer</strong></p>
<p>All single-entity child objects on the root will have their respective INSERT methods called first. If you think about it, this makes sense. The primary key of each child object is used as a foreign key on the parent object, so the child object primary key has to be known BEFORE the parent object can be saved. Thus, for a new Customer object, we have to first insert it into the DB and return the newly generated CustomerId to the Ticket BEFORE the Ticket gets saved.  </p>
<pre name="code" class="c-sharp">
public void Insert(Customer customer)
{
    customer.CustomerId = _customerDataSource.Insert(customer);
}
</pre>
<p>So here we&#8217;re passing the Customer to a class that will perform the actual INSERT into Oracle, and in turn that method will get the generated PK from Oracle and return it. It is then our responsibility in this call to associate that PK with the Customer object, because the Customer is going to get sent back across the wire to the client when RIA is done making all these calls. </p>
<p><strong>Inserting a Ticket</strong></p>
<p>Once the Customer has been saved to the DB (and the new CustomerId returned and set on the Customer object) then RIA will call the INSERT method for the Ticket itself. At this point in time we need to set the CustomerId (and any other child foreign keys) on the Ticket object:</p>
<pre name="code" class="c-sharp">
public void Insert(Ticket ticket)
{
      ticket.CustomerId = ticket.Customer.CustomerId;

      ticket.TicketId = _ticketDataSource.Insert(ticket);

      foreach (var ticketAction in ticket.TicketActions)
      {
        ticketAction.TicketId = ticket.TicketId;
      }
}
</pre>
<p>And just like the Customer INSERT method, once we save the Ticket to the database we need to get the generated PK back from Oracle and set it on our Ticket. </p>
<p><strong>Inserting TicketActions</strong></p>
<p>The last thing that happens here is the insertion of multiple TicketActions, as this is a child collection on the Ticket object. And again, if you think about it from a DB point of view, this makes sense. Each TicketAction has a foreign key TicketId. Thus, a TicketAction can&#8217;t be saved to the DB until the TicketId is known. For a new Ticket, that won&#8217;t be until the Ticket is saved and the id returned. Once the Ticket&#8217;s primary key (TicketId) is known, we can attach it to each TicketAction and save them as well. RIA will make that call automatically, after the INSERT method for the Ticket is done: </p>
<pre name="code" class="c-sharp">
public void InsertTicketAction(TicketAction ticketAction)
{
      ticketAction.TicketActionId = _ticketActionDataSource.Insert(ticketAction);
}
</pre>
<p><strong>Done Inserting</strong></p>
<p>Once all of those calls are made and the various pieces of data have been saved to their respective tables, the root aggregate object is ready to be reloaded by RIA. This will happen AUTOMATICALLY. You do not need to call Load() on the service context again in your ViewModel after you have called SubmitChanges(). RIA will automatically reload your entity client-side depending on what kind of LoadBehavior you specified (for this project we&#8217;ve specified a LoadBehavior.RefreshCurrent). This is another reason why it is so important to return the primary keys and set those values on the objects when you saved that data to the database. </p>
<p>Next time I&#8217;ll cover UPDATE operations and explain one of the quirks of RIA sending entities down the wire&#8230;. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisholmesonline.com/2011/01/19/silverlight-ria-services-with-poco-oracle-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Silverlight RIA Services with POCO &amp; Oracle: Part I</title>
		<link>http://www.chrisholmesonline.com/2011/01/13/silverlight-ria-services-with-poco-oracle-part-i/</link>
		<comments>http://www.chrisholmesonline.com/2011/01/13/silverlight-ria-services-with-poco-oracle-part-i/#comments</comments>
		<pubDate>Thu, 13 Jan 2011 21:31:13 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Work Related]]></category>

		<guid isPermaLink="false">http://www.chrisholmesonline.com/?p=540</guid>
		<description><![CDATA[There are a lot of Silverlight + RIA samples all over the internet and many of these will happily show you how to properly build functionality with these emerging technologies. Unfortunately, they all seem to be built on the notion that you will be using Microsoft&#8217;s Entity Framework with SQL Server for your database needs. [...]]]></description>
			<content:encoded><![CDATA[<p>There are a lot of Silverlight + RIA samples all over the internet and many of these will happily show you how to properly build functionality with these emerging technologies. Unfortunately, they all seem to be built on the notion that you will be using Microsoft&#8217;s Entity Framework with SQL Server for your database needs. Well, where I work, we are tied to an Oracle database and thus the Entity Framework is not really an option. So how could we make this work? I&#8217;m going to show you. </p>
<p>Disclaimer: I don&#8217;t proclaim to be a Silverlight or RIA expert. This is just a account of what we discovered when building applications with Silverlight and RIA Services against an Oracle database. </p>
<div style="border:solid 1px gray;padding:5px;background:lightgray;">
The source code for this (and related posts) can be found <a href="http://www.chrisholmesonline.com/SilverlightAggregate.zip">here</a>. This is a Visual Studio 2010 Solution.</div>
<p><strong>The Application</strong></p>
<p><img src="http://www.chrisholmesonline.com/images/SilverlightAggregateApp.png" width='800'  alt="Silverlight Aggregate Application" /></p>
<p>This is a simple ticketing application example. Companies use these sorts of applications to track call and customer interactions. Operations you can perform: </p>
<ul>
<li>Open a Ticket</li>
<li>Create a new Ticket</li>
<li>Search for a Customer when creating a new Ticket</li>
<li>Log a Ticket Action</li>
<li>View the History of Ticket Actions</li>
<li>Edit Customer data when saving a Ticket</li>
<li>Edit Product (via dropdown selection) on an existing Ticket</li>
</ul>
<p>In our production environment we write these applications against an Oracle database. For the purposes of this demo, everything is stored in memory. But the data access part of the RIA Service is abstracted, so you should be able to see how easy it is to hand operations off to a data access layer to work against your preferred database. </p>
<p><strong>Complex Aggregate Roots</strong></p>
<p>To start with, many of the samples for Silverlight and RIA on the internet are very simple. They show basic entities in relatively simple scenarios. A lot of the &#8220;magic&#8221; happens by just calling on the Entity Framework inside the RIA Services context. We all know by now that&#8217;s not the way the real world works, and the first time you try and do something outside the scope of a demo you run into headaches. </p>
<p>What I am going to show you here is a complex root aggregate object that is actually structurally identical to one we used in our real production application. I&#8217;ve trimmed it down some (removed a few entities for brevity), but the <em>structure </em>is the same. The core pieces to this aggregate are such: </p>
<ul>
<li>A root parent object</li>
<li>Multiple child objects contained in the root</li>
<li>A List of child objects</li>
<li>Child objects on the list of child objects</li>
</ul>
<p>Does that sound more like a real world scenario to you? Good, me too. Here&#8217;s an object graph to help visualize: </p>
<p><img src="http://www.chrisholmesonline.com/images/RootAggregate2.png" alt="Root Aggregate" width='800' /></p>
<p>Each child object represents a table in an Oracle database. Our goal with our RIA service is to be able to query the child objects (Product, Customer, TicketAction, ActionType, ResultType) separately (so we can fill in dropdowns and forms) and to be able to query and save the root aggregate (Ticket) as an entire object graph all at once. To make this happen, we have to do two things. </p>
<p>First, we have to setup the metadata correctly so that the associations between the objects can be understood by RIA, because RIA is going to do a lot of magic for us. Second, we have to develop the code inside our RIA Service methods properly so that data gets inserted/updated in the proper order when we&#8217;re saving an object graph. </p>
<p><strong>Metadata &#038; Foreign Keys</strong></p>
<p>In a typical database scenario, you&#8217;re going to have a parent table that will contain the foreign keys of the child tables. However, when you want to actually work with this data in code, you don&#8217;t want just the keys to those children showing up in your root object/entity &#8211; you want the whole child object/entity. When using an O/RM this sort of thing is handled for us automatically. But when you&#8217;re using more primitive database access technologies (ADO.NET with Oracle) then you have to account for these facts yourself. With RIA Services we can make this happen, but we have to provide the parent object with <strong>both </strong>pieces of data: the foreign key to the child object AND the child object itself. </p>
<pre name="code" class="c-sharp">
  [MetadataType(typeof (TicketMetadata))]
  public partial class Ticket
  {
    internal sealed class TicketMetadata
    {
      [Key] public int TicketId;

      [Required]
      public DateTime IncidentDate;

      public int CustomerId;

      [Required]
      [Range(1, 99999999, ErrorMessage = "Must select a Product")]
      public int ProductId; 

      [Include]
      [Association("Ticket_Customer", "CustomerId", "CustomerId", IsForeignKey = true)]
      public Customer Customer;

      [Include]
      [Association("Ticket_Product", "ProductId", "ProductId", IsForeignKey = true)]
      public Product Product;

      [Include]
      [Composition]
      [Association("Ticket_TicketActions", "TicketId", "TicketId")]
      public List<TicketAction> TicketActions;
    }
  }
</pre>
<p>As you can see, we have the <strong>ProductId </strong>and <strong>Product </strong>as properties on the Ticket (same with CustomerId and Customer). We instruct RIA to associate these two things via this line:</p>
<pre name="code" class="c-sharp">
[Include]
[Association("Ticket_Product", "ProductId", "ProductId", IsForeignKey = true)]
public Product Product;
</pre>
<p>The important part here is to set the IsForeignKey = true. RIA Services will use this to association to copy key values among related entities. So, for instance, when you set a Product with a ProductID = 3 on the Ticket (parent) object, RIA&#8217;s proxy class for Ticket knows to automatically set the Ticket.ProductId = 3. </p>
<p><strong>Collections</strong></p>
<p>Collections are handled slightly differently from individual child objects. There are a couple of ways to deal with them, and your choices depends on whether or not you want your child objects in the collection to be accessible as separate methods on the RIA Service, or only through the parent object. In our case, we wanted these particular child objects to only be accessible via the parent object, so we utilize the Composition attribute. The Composition attribute is <a href="http://blogs.msdn.com/b/digital_ruminations/archive/2009/11/18/composition-support-in-ria-services.aspx">well documented</a>. The highlights: </p>
<ul>
<li>Hierarchical change tracking – when a child entity is modified, it’s parent also transitions to the Modified state.</li>
<li>When a parent is in the Modified state, all of its children are included in the change-set sent to the server, including any Unmodified children.</li>
<li>Operation ordering – Often only CRUD operations for the parent or root type in a compositional hierarchy will be exposed by a DomainService. This allows you to write all your business logic for a hierarchy in a single method. However writing explicit methods for child Types is supported, <em>in which case parent operations are always called before child operations</em>. For example, if a new OrderDetail was added to an existing PurchaseOrder, the Update method for PurchaseOrder would be called before the Insert for the OrderDetail.</li>
<li>Public EntitySets for child Types are not generated on the code-genned DomainContext. Children are only accessible via their parent relationship.</li>
</ul>
<p>Take note of the third item:<em> parent operations are always called before child operations</em>. When you&#8217;re writing RIA Services, order of operations is important. As you begin to develop your data access code (whether it&#8217;s Oracle or some other DB) it is important to pay attention to the order of the calls as RIA makes them. Returning surrogate keys from INSERT operations will be important when dealing with parent and child data. </p>
<p><strong>The RIA Service</strong></p>
<p>The nuts and bolts of this application lies in the service layer. I&#8217;m going to post the code so you can see how simple it is. In the next post, I&#8217;ll talk about order of operations &#8211; how the calls get made by RIA and in what order, and why you have to do things a certain way. </p>
<pre name="code" class="c-sharp">
  [EnableClientAccess()]
  public class TicketService : DomainService
  {
    private TicketDataSource _ticketDataSource;
    private CustomerDataSource _customerDataSource;
    private ProductDataSource _productDataSource;
    private ActionTypeDataSource _actionTypeDataSource;
    private ResultTypeDataSource _resultTypeDataSource;
    private TicketActionDataSource _ticketActionDataSource;

    public TicketService()
    {
      _ticketDataSource = new TicketDataSource();
      _customerDataSource = new CustomerDataSource();
      _productDataSource = new ProductDataSource();
      _actionTypeDataSource = new ActionTypeDataSource();
      _resultTypeDataSource = new ResultTypeDataSource();
      _ticketActionDataSource = new TicketActionDataSource();
    }

    public IQueryable<Ticket> GetTicketById(int id)
    {
      var tickets = _ticketDataSource.GetTickets();
      return tickets.Where(x => x.TicketId == id).AsQueryable();
    }

    public IQueryable<Ticket> GetTickets()
    {
      return _ticketDataSource.GetTickets().AsQueryable();
    }

    public void Insert(Ticket ticket)
    {
      if (ticket.CustomerId == 0)
        ticket.CustomerId = ticket.Customer.CustomerId;

      ticket.TicketId = _ticketDataSource.Insert(ticket);

      foreach (var ticketAction in ticket.TicketActions)
      {
        ticketAction.TicketId = ticket.TicketId;
      }
    }

    public void Update(Ticket ticket)
    {
      foreach (var ticketAction in ticket.TicketActions)
      {
        if (ticketAction.IsNew)
          ticketAction.TicketId = ticket.TicketId;
      }

      _ticketDataSource.Update(ticket);
    }

    public void InsertTicketAction(TicketAction ticketAction)
    {
      ticketAction.TicketActionId = _ticketActionDataSource.Insert(ticketAction);
    }

    public IQueryable<Product> GetProducts()
    {
      return _productDataSource.GetProducts().AsQueryable();
    }

    public IQueryable<ActionType> GetActionTypes()
    {
      return _actionTypeDataSource.GetActionTypes().AsQueryable();
    }

    public IQueryable<ResultType> GetResultTypes()
    {
      return _resultTypeDataSource.GetResultTypes().AsQueryable();
    }

    public IQueryable<Customer> GetCustomers()
    {
      return _customerDataSource.GetCustomers().AsQueryable();
    }

    public IQueryable<Customer> GetCustomersBySearchCriteria(string firstName, string lastName, string phone)
    {
      return _customerDataSource.GetCustomersBySearchCriteria(firstName, lastName, phone).AsQueryable();
    }

    public void Insert(Customer customer)
    {
      _customerDataSource.Insert(customer);
    }

    public void Update(Customer customer)
    {
      _customerDataSource.Update(customer);
    }
  }
</pre>
<p>This post is already long. Part 2 coming soon!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisholmesonline.com/2011/01/13/silverlight-ria-services-with-poco-oracle-part-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Coloring a DataGridCell in WPF</title>
		<link>http://www.chrisholmesonline.com/2010/09/09/coloring-a-datagridcell-in-wpf/</link>
		<comments>http://www.chrisholmesonline.com/2010/09/09/coloring-a-datagridcell-in-wpf/#comments</comments>
		<pubDate>Thu, 09 Sep 2010 15:02:40 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Work Related]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://www.chrisholmesonline.com/?p=520</guid>
		<description><![CDATA[This question popped up on StackOverflow and it prompted me to write some code. At first I thought, &#8220;Okay, someone will answer this soon, I&#8217;m sure.&#8221; But after I left it alone all night and returned in the morning I found it still unanswered. As I find this to be a common request when it [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://stackoverflow.com/questions/3671003/wpf-how-to-get-a-cell-from-a-datagridrow/3676410#3676410">This question</a> popped up on <a href="http://stackoverflow.com/questions/3671003/wpf-how-to-get-a-cell-from-a-datagridrow/3676410#3676410">StackOverflow</a><br />
and it prompted me to write some code. At first I thought, &#8220;Okay, someone will answer this soon, I&#8217;m sure.&#8221; But after I left it alone all night and returned in the morning I found it still unanswered. As I find this to be a common request when it comes to DataGrids I decided to write some code and figure it out myself. </p>
<p>The solution is posted on the StackOverflow thread. I wrote a small demo application to show how this works. You can download it <a href="http://www.chrisholmesonline.com/DataGridSample.zip">here</a>. For posterity sake, I&#8217;ll repeat the solution here.</p>
<p><strong>Don&#8217;t Fight The Framework</strong></p>
<p>A note on WPF: If you read the <a href="http://stackoverflow.com/questions/3671003/wpf-how-to-get-a-cell-from-a-datagridrow/3676410#3676410">original question</a> on StackOverflow, you&#8217;ll notice the original poster was trying to accomplish their goal via code-behind. This is simply the wrong way to go about using WPF. It&#8217;s a classic case of developer with WinForms experience trying to use the WinForms sledgehammer to make WPF do their bidding. Wrong approach. </p>
<p>WPF is a totally different animal than classic WinForms. It is more robust, to be sure, and that can translate into &#8220;more complex&#8221; with a &#8220;steeper learning curve&#8221;. But the end result is a technology that is far more flexible and powerful than it&#8217;s pathetic predecessor. Learning how the technology expects you to do things is the first step in leveraging the power of technology to do your bidding. </p>
<p>In this particular case, what we need to understand is that WPF is setup very nicely to handle styling of visual elements. In this specific case, it&#8217;s a prime candidate for an <a href="http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx">IValueConverter</a> implementation and a simple styling rule. </p>
<p><strong>Setting The Style</strong></p>
<p>Like all controls, the DataGrid can be styled, and these style settings can target specific elements of the grid. In this case, we want to style the DataGridCell&#8217;s Background property. We&#8217;ll do that by declaring a style setting within the DataGrid XAML markup: </p>
<pre name="code" class="xml">
&lt;toolkit:DataGrid.CellStyle&gt;
          &lt;Style TargetType="{x:Type toolkit:DataGridCell}"&gt;
            &lt;Style.Setters&gt;
              &lt;Setter Property="Background"
                   Value="{Binding RelativeSource={RelativeSource Self},
                   Path=Content.Text,
                   Converter={StaticResource dataGridCellTextToColorConverter}}" /&gt;
            &lt;/Style.Setters&gt;
          &lt;/Style&gt;
        &lt;/toolkit:DataGrid.CellStyle&gt;
</pre>
<p>What we&#8217;re doing here is declaring a style for the DataGridCell. We&#8217;re specifying the Background as the property to set, and we&#8217;re saying that we&#8217;re going to allow an IValueConverter (dataGridCellTextToColorConverter) to handle the calculation of the exact value to set. We&#8217;re passing the converter the value of the DataGridCell&#8217;s Content.Text property. </p>
<p><strong>Coding The IValueConverter</strong></p>
<p>IValueConverter is a really simple interface to implement. In this case, we&#8217;re only concerned with the Convert() method because we&#8217;re only binding values one-way. </p>
<p>Note: I&#8217;ve done some extra work here in the constructor of this class to codify a dictionary of text values and colors. You could do this sort of thing a lot of different ways; you could pull these values from a database on application startup and cache them in your app if you wanted to; whatever you feel like doing. I did this for ease of use. </p>
<pre name="code" class="c-sharp">
public class DataGridCellTextToColorConverter : IValueConverter
  {
    public IDictionary<string, string> _colors;
    public DataGridCellTextToColorConverter()
    {
      _colors = new Dictionary<string, string>();
      _colors["COMEDY"] = "GREEN";
      _colors["SCIENCE FICTION"] = "RED";
      _colors["DRAMA"] = "ORANGE";
    }
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      if (value == null) return Colors.White.ToString();
      foreach(var color in _colors)
      {
        if (value.ToString().ToUpper().Contains(color.Key))
          return color.Value;
      }
      return "WHITE";
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
      throw new NotImplementedException();
    }
  }
</pre>
<p>Here, we&#8217;re checking the colors dictionary to see if any text keys match, and if so, we&#8217;re returning the corresponding color value. In WPF, the colors are <strong>HTML color values</strong>, so you can use named colors from the HTML color table or you can use values like #006688. </p>
<p><strong>Resource Declaration</strong></p>
<p>Once the IValueConverter is coded, we simply need to reference it in our view as an appropriate Resource. </p>
<pre  name="code" class="xml">&lt;Window.Resources&gt;
    &lt;Converters:DataGridCellTextToColorConverter x:Key="dataGridCellTextToColorConverter"/&gt;
  &lt;/Window.Resources&gt;
</pre>
<p>And with that, you should have a working method for changing the colors on a DataGrid based on values in the cell. Enjoy. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisholmesonline.com/2010/09/09/coloring-a-datagridcell-in-wpf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WPF: Async Calls</title>
		<link>http://www.chrisholmesonline.com/2010/07/23/wpf-async-calls/</link>
		<comments>http://www.chrisholmesonline.com/2010/07/23/wpf-async-calls/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 14:19:51 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Work Related]]></category>

		<guid isPermaLink="false">http://www.chrisholmesonline.com/?p=515</guid>
		<description><![CDATA[While working on a project at my new job I ran across a problem where I needed to update a WPF UI (databound collection) from an async call. There are tons of examples on the internet of how to do this, but few of them seem tailored for the MVVM model where your ViewModel doesn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>While working on a project at my new job I ran across a problem where I needed to update a WPF UI (databound collection) from an async call. There are tons of examples on the internet of how to do this, but few of them seem tailored for the MVVM model where your ViewModel doesn&#8217;t have knowledge of the view (and thus doesn&#8217;t have access to the view&#8217;s Dispatcher). For scalar types this isn&#8217;t a problem as they are marshaled to the UI thread in WPF, but for collections bound to controls, this becomes asynchronous updating is an issue. </p>
<p>Fortunately, <strong>Jeremy Likness</strong> came up with an elegant solution. Instead of regurgitating what he did, I&#8217;ll just point you to his blog post. While is post is about Silverlight, this is also applicable to WPF. </p>
<p>I thought his solution was simple &#038; elegant (and best of all, it works!)</p>
<p><a href="http://www.wintellect.com/CS/blogs/jlikness/archive/2009/12/16/dispatching-in-silverlight.aspx">Dispatching In Silverlight</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisholmesonline.com/2010/07/23/wpf-async-calls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Job</title>
		<link>http://www.chrisholmesonline.com/2010/06/28/new-job/</link>
		<comments>http://www.chrisholmesonline.com/2010/06/28/new-job/#comments</comments>
		<pubDate>Mon, 28 Jun 2010 16:05:13 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Work Related]]></category>

		<guid isPermaLink="false">http://www.chrisholmesonline.com/?p=513</guid>
		<description><![CDATA[I figure it&#8217;s time to make the announcement here since I keep getting job offers from around the country. I&#8217;ve accepted a job in Johnson City, TN. I am officially off the market. I think it&#8217;s going to be a very cool place to work. Fast paced, challenging, with good people to work with. I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<p>I figure it&#8217;s time to make the announcement here since I keep getting job offers from around the country. </p>
<p>I&#8217;ve accepted a job in <strong>Johnson City, TN</strong>. I am officially off the market. </p>
<p>I think it&#8217;s going to be a very cool place to work. Fast paced, challenging, with good people to work with. I&#8217;m excited. And really, what more can you ask for? </p>
<p>My thanks to the various companies who reached out to me the past month and a half. Some of you had some very nice offers with some really intriguing job opportunities. Sadly, most of them were not in the Tri-Cities area of TN where I needed to move to <img src='http://www.chrisholmesonline.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>But who knows what the future holds? I am selling a house I bought four months ago because I thought I was going to be here in Idaho for another 2-5 years. I am not clairvoyant; situations change. We&#8217;ll see what happens.</p>
<p>In the meantime, very much looking forward to moving to VA/TN and seeing how this all plays out. Time to begin again!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisholmesonline.com/2010/06/28/new-job/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

