John Smith's Blog

Keeping the fun machine running one nickel at a time


News

My Stats

  • Posts - 21
  • Comments - 30
  • Trackbacks - 0

Twitter












Recent Comments


Recent Posts


Article Categories


Archives


Post Categories


Image Galleries


 

My coworkers setup  a nice way to get the fault messages from our service layer all the way back to the client’s service proxy layer.  This is what I needed to work on this afternoon.  Through a series of trials and errors I finally figured this out.

The confusion was how I was looking at the exception in the quick watch viewer.  It appeared as though the EventArgs from the service call had somehow magically been cast back to FaultException(), not FaultException<T>. 

I drilled into the EventArgs object with the quick watch and I copied this code to figure out where the Fault message was hiding.  Further, when I copied this quick watch code into the IDE I got squigglies.  Poop.

   1: ((System
   2:   .ServiceModel
   3:   .FaultException<UnhandledExceptionFault>)(((System.Exception)(e.Result)).InnerException)).Detail.FaultMessage

I wont bore you with the details but here’s how it turned out.  

EventArgs which I’m calling “e” is not the result such as some collection of items you’re expecting.  It’s actually a FaultException, or in my case FaultException<T>.  Below is the calling code and the callback to handle the expected response or the fault from the completed event.

   1: public void BeginRetrieveItems(Action<ObservableCollection<Model.Widget>> FindItemsCompleteCallback, Model.WidgetLocation location)
   2: {
   3:     var proxy = new MyServiceContractClient();
   4:  
   5:     proxy.RetrieveWidgetsCompleted += (s, e) => FindWidgetsCompleteCallback(FindWidgetsCompleted(e));
   6:  
   7:     RetrieveWidgetsRequest request = new RetrieveWidgetsRequest { location.Id };
   8:  
   9:     proxy.RetrieveWidgetsAsync(request);
  10: }
  11:  
  12: private ObservableCollection<Model.Widget> FindItemsCompleted(RetrieveWidgetsCompletedEventArgs e)
  13: {
  14:     if (e.Error is FaultException<UnhandledExceptionFault>)
  15:     {
  16:         var fault = (FaultException<UnhandledExceptionFault>)e.Error;
  17:         var faultDetailMessage = fault.Detail.FaultMessage;
  18:  
  19:         UIMessageControlDuJour.Show(faultDetailMessage);
  20:         return new ObservableCollection<BinInventoryItemCountInfo>();
  21:     }
  22:  
  23:     var widgets = new ObservableCollection<Model.Widget>();
  24:  
  25:     if (e.Result.Widgets != null)
  26:     {
  27:         e.Result.Widgets.ToList().ForEach(w => widgets.Add(this.WidgetMapper.Map(w)));
  28:     }
  29:  
  30:     return widgets;
  31: }

 

I recently was given an assignment to create a UX where a user could use the up and down arrow keys, as well as the tab and enter keys to move through a Silverlight datagrid that is going be used as part of a high throughput data entry UI.

And to be honest, I’ve not trapped key codes since I coded JavaScript a few years ago.  Although the frameworks I’m using made it easy, it wasn’t without some trial and error. 

 

The other thing that bothered me was that the customer tossed this into the use case as they were delivering the use case.  Fine.  I’ll take a whack at anything and beat up myself and beg (I’m not beyond begging for help) the community for help to get something done if I have to.

It wasn’t as bad as I thought and I thought I would hopefully save someone a few keystrokes if you wanted to build a green screen for your customer.

 

Here’s the ValueConverter to handle changing the strings to decimals and then back again.  The value is a nullable valuetype so there are few extra steps to take.  Usually the “ConvertBack()” method doesn’t get addressed but in this case we have two-way binding and the converter needs to ensure that if the user doesn’t enter a value it will remain null when the value is reapplied to the model object’s setter. 

   1: using System;
   2: using System.Windows.Data;
   3: using System.Globalization;
   4:  
   5: public class NullableDecimalToStringConverter : IValueConverter
   6: {
   7:     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   8:     {
   9:         if (!(((decimal?)value).HasValue))
  10:         {
  11:             return (decimal?)null;
  12:         }
  13:         if (!(value is decimal))
  14:         {
  15:             throw new ArgumentException("The value must be of type decimal");
  16:         }
  17:  
  18:         NumberFormatInfo nfi = culture.NumberFormat;
  19:         nfi.NumberDecimalDigits = 4;
  20:  
  21:         return ((decimal)value).ToString("N", nfi);
  22:     }
  23:  
  24:     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  25:     {
  26:         decimal nullableDecimal;
  27:         decimal.TryParse(value.ToString(), out nullableDecimal);
  28:  
  29:         return nullableDecimal == 0 ? null : nullableDecimal.ToString();
  30:     }
  31: }

          

The ConvertBack() method uses TryParse to create a value from the incoming string so if the parse fails, we get a null value back, which is what we would expect.  But while I was testing I realized that if the user types something like “2..4” instead of “2.4”, TryParse will fail and still return a null.  The user is getting “puuu-lenty” of eye-candy to ensure they know how many values are affected in this particular view.

Here’s the XAML code.   This is the simple part, we just have a DataGrid with one column here that’s bound to the the appropriate ViewModel property with the Converter referenced as well.

   1: <data:DataGridTextColumn 
   2:     Header="On-Hand" 
   3:     Binding="{Binding Quantity, 
   4:               Mode=TwoWay, 
   5:               Converter={StaticResource DecimalToStringConverter}}" 
   6:     IsReadOnly="False" />

Nothing too magical here.  Just some XAML to hook things up.

 

Here’s the code behind that’s handling the DataGridKeyup event.  These are wired to a local/private method but could be converted to something the ViewModel could use, but I just need to get this working for now.

   1: // Wire up happens in the constructor
   2: this.PicDataGrid.KeyUp += (s, e) => this.HandleKeyUp(e);

 

   1: // DataGrid.BeginEdit fires when DataGrid.KeyUp fires.
   2: private void HandleKeyUp(KeyEventArgs args)
   3: {
   4:      if (args.Key == Key.Down || 
   5:          args.Key == Key.Up || 
   6:          args.Key == Key.Tab || 
   7:          args.Key == Key.Enter )
   8:      {
   9:          this.PicDataGrid.BeginEdit();
  10:      }
  11: }

 

And that’s it.  The ValueConverter was the biggest problem starting out because I was using an existing converter that didn’t take nullable value types into account.   Once the converter was passing back the appropriate value (null, “#.####”) the grid cell(s) and the model objects started working as I needed them to.

HTH.