Programming+

Random programming things I'd want to remember

Saturday, March 22, 2014

Code snippet for MVVM command in a ViewModel

Since code snippets are not that hard to do, here is another one. This one gets all the plumbing for a command in a ViewModel, I used DelegateCommand class to abstract all the INotifyPropertyChanged functionality. See my other posts on the subject. Call this one in VisualStudio by its shortcut, dcmvvm.
<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets
    xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Plumbing for an MVVM DelegateCommand</Title>
      <Author>yevgeller</Author>
      <Description>Plumbing for an MVVM DelegateCommand for use in a ViewModel</Description>
      <Shortcut>dcmvvm</Shortcut>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>cmd1</ID>
          <ToolTip>Prefix for a private variable that holds command name.</ToolTip>
          <Default>your</Default>
        </Literal>
        <Literal>
          <ID>cmd2</ID>
          <ToolTip>Prefix for a property Name that exposes the command to the View.</ToolTip>
          <Default>Your</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[
        DelegateCommand _$cmd1$Command;
        public ICommand $cmd2$Command { get { return _$cmd1$Command; } }
        private void $cmd2$CommandAction(object obj)
        {
            throw new NotImplementedException();
        }
        //one more thing: add the following line to ViewModel constructor or wherever else you initialize your commands:
        _$cmd1$Command = new DelegateCommand(this.$cmd2$CommandAction);
      ]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

Tuesday, March 18, 2014

Code snippet file for a property that calls for OnPropertyChanged event

With minimal changes, this snippet will also work for PropertyChanged event. How to use:
  1. Save the following contents into a .snippet file
  2. Visual Studio -> Tools -> Code Snippets Manager (or Ctrl+K, Ctrl+B)
  3. Import, find your file
  4. While working on another ViewModel, type in propopc and enjoy

Note to self: while working on the next snippet, if variables don't show up in the result, make sure that they are included in the <Snippet> section

Helpful resource 1, helpful resource 2.

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets
    xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Property with a call to OnPropertyChanged</Title>
      <Author>yevgeller</Author>
      <Description>Property calling OnPropertyChanged method</Description>
      <Shortcut>propopc</Shortcut>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>var</ID>
          <ToolTip>Replace with a private variable.</ToolTip>
          <Default>_privateVar</Default>
        </Literal>
        <Literal>
          <ID>type</ID>
          <ToolTip>Replace with a property type.</ToolTip>
          <Default>string</Default>
        </Literal>
        <Literal>
          <ID>propName</ID>
          <ToolTip>Replace with a property name.</ToolTip>
          <Default>MyProperty</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[
  private $type$ $var$;
         public $type$ $propName$
         {
              get { return $var$; }
              set
              {
                  if ($var$ == value) return;
                  $var$ = value;
                  OnPropertyChanged("$propName$");
              }
         }
      ]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

Monday, March 17, 2014

One of the uses for Visual Studio's Output window

I am generating some dummy data for testing every time I build and run a program, and I need to look something up every time. Being a lazy programmer, I was wondering if there is a way in Visual Studio to display something during compile time. I found that if execute this code:
System.Diagnostics.Debug.WriteLine("Hello, World!");
Then it will be display along with a bunch of other compilation info in the Output Window. Oh, yeah, Output window in Visual Studio is also extremely useful for displaying XAML binding information.

Wednesday, March 12, 2014

ASP.Net Web API with Angular.js front-end example

I wanted to learn about Microsoft ASP.Net Web API and how I could use Angular.js framework as a front-end. I built a little application that demonstrates the basics.

This app was heavily influenced by this tutorial (especially parts 3-5), and this book's chapter on Web API.

The code is available on Github here.

The project has two controllers: HomeController and RecordController. HomeController is the ASP.Net MVC controller while RecordController deals with Web API. The Web API data infrastructure is in /Models folder. The script file is in /Scripts/Home/record.js. One last thing I need is a view, so there is a view RecordsApi.cshtml under /Views/Home

The view has all the regular angular directives. It uses /Scripts/Home/records.js file which has all the Angular.js stuff. I use $http service to communicate with the server.

In short, ajax calls are replaced with calls to the corresponding methods of Angular's $http service. The view is created as usual, API controller is the same as it would be for a regular Web API service, and models are done in the same way. The only difference you need to make if you want Angular.js front-end is to introduce angular script in the view and put all the directives in place.

Comments/questions are welcome.


Friday, February 28, 2014

Another simple MVVM tutorial for Windows Phone explained

I will take another attempt to explain the use of MVVM on Windows Phone. I already tried it before, but this time code is available on GitHub. Clone the project and follow along with my explanations.

This time we are building a registration database. The app will be tracking people's names along with gender.

1. Model

There is a class called "Person" in the Models folder. For the sake of simplicity, the app will track the name and gender.

2. View

There is MainPage.xaml file in ViewModels folder that is the front-end of the app (to change startup page for a Windows Phone app, go to Properties/WMAppManifest.xml and change it in "Navigation Page" field to whatever you need; the sample app already has it set up properly). There is a textbox for name, and radiobuttons to select a gender. The app must only allow to register when a name is provided and a gender is selected. So it can either provide feedback to the user when not all data is supplied for registration, or we can disable the Register button until all data is present.

There is a tricky part here. TextBox's text property originally had the following binding:

Text="{Binding UserName, Mode=TwoWay}"
The problem with that is that the Text property is updated in the view model only after textbox loses focus. To mitigate the situation, we can use the solution provided by Charles Petzold in his "Programming Windows Phone 7" book:
<!-- TextBox full declaration in XAML -->
<TextBox Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=Explicit}" 
                     x:Name="boundTextBox" 
                     TextChanged="boundTextBox_TextChanged" />

//and then, the event in the code-behind file for the View:
private void boundTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
  TextBox txtbox = sender as TextBox;
  BindingExpression bindingExpression = txtbox.GetBindingExpression(TextBox.TextProperty);
  bindingExpression.UpdateSource();
}

As a result of this modification, every time a key is pressed in that TextBox, the property in our view model will be updated. One can argue that the true MVVM has no data in the code-behind files and this event might violate that principle, but the reality is that sometimes it's not easily possible. In addition, one of the main benefits of MVVM is testability. Having such an event in the code-behind of the view only affects internal workings of the app and does not affect data or business logic, so testability is very much preserved intact.

Now let's look a little closer at bindings. RegisterViewModel exposes properties and commands, which the view uses to display data or react to user input. For example, RegisterViewModel exposes a property named ProspectiveRegistration, which it calculates as as combination of name and gender:

public string ProspectiveRegistration
{
    get
    {
        string ret = this.UserName;
        ret += this.UserName.Length > 0 ? ", " : "";

        if (this.IsALady)
            ret += "Lady";
        if (this.IsAGentleman)
            ret += "Gentleman";

        return ret;
    }
}
The view binds this property to a TextBlock's Text property in the following manner:
<TextBlock Text="{Binding ProspectiveRegistration}" />
How does the view know that the property was updated? The answer to that lies in the setters of the all the other properties used in ProspectiveRegistration (UserName, IsALady, IsAGentleman). They all have the following line of code:
this.OnPropertyChanged("ProspectiveRegistration");
This line of code is the magic that updates the view with the new value of the property.

The example above was somewhat simple because the view only displayed the value of a property that belongs to the view model. What if the view needs to send data back to the ViewModel? Let's look at how the gender radiobuttons are declared:

<RadioButton Content="Lady" IsChecked="{Binding IsALady, Mode=TwoWay}" GroupName="genderGroup" />
IsChecked property is declared as a two-way property, and not only it displays the state of the property in the view model, but it also sends its value back to the view model. This is one of the ways how the view propagates data to the view model.

3. ViewModel

The view model for the project is the class called RegisterViewModel and it resides in the ViewModels folder along with the class called ViewModel. ViewModel class is the parent class for RegisterViewModel and it has the plumbing for INotifyPropertyChanged interface. It also has plumbing for navigation since it may be a bit tricky if using MVVM, but there are usage instructions.

RegisterViewModel.cs

A couple of interesting points here. First, the data store is an ObservableCollection. The difference between an ObservableCollection and List is that ObservableCollection lets know when it changed. The app conveniently subscribes to the CollectionChanged event to update properties bound to the view.

Next, let's look at the register command. Declaration:

private DelegateCommand _registerCommand;
It is an instance of a DelegateCommand. What is a DelegateCommand? Any command bound to the view must implement ICommand interface. DelegateCommand wraps up all the members of the ICommand interface so that the app does not have to re-implement them every time. DelegateCommand.cs can be found in ServiceClasses folder.

_registerCommand as it is declared in constructor of the RegisterViewModel:

_registerCommand = new DelegateCommand(this.RegisterCommandAction, CanRegister); //initialize command
Method RegisterCommandAction is where the registration actually happens. This is what the command is supposed to do:
//Registration procedure
private void RegisterCommandAction(object obj)
{
    people.Add(new Person
    {
        Name = this.UserName,
        Gender = this.IsALady ? "Lady" : "Gentleman"
    });
    this.UserName = "";
    this.IsALady = false;
    this.IsAGentleman = false;
}
CanRegister method defines whether the command can execute or not. Here is what it looks like:
//Data consistency conditions that must be satisfied for a successful registration
private bool CanRegister(object arg)
{
    return (IsALady || IsAGentleman) && UserName.Length > 0;
}
This method enables/disables the register button in the view without having to bind the IsEnabled property of the button on the view. By the way, IsEnabled property can be managed by binding this property on the view to a boolean property on a view model. Pretty much any property on the view can be bound to a property on the view model, sometimes one might need to use a converter class (any class that implements an IValueConverter interface).

There is just one piece missing. The app somehow needs to know when CanRegsiter changes. For that, the DelegateCommand exposes a method called RaiseCanExecuteChanged(). Every time a property changes in the RegisterViewModel, not only the app has to notify that the property value changed, but it also has to make sure we can (or cannot) register. Here is, for example, an implementation of the UserName property in the view model:

private string _userName;
public string UserName
{
    get
    {
        if (_userName == null)
            _userName = "";
        return _userName;
    }
    set
    {
        if (_userName == value)
            return;
        _userName = value;
        this.OnPropertyChanged("UserName");
        this.OnPropertyChanged("ProspectiveRegistration");
        _registerCommand.RaiseCanExecuteChanged(); //checking on RegisterCommand to see if it can execute
    }
}

4. Testing

Now you can see that MVVM decouples View from ViewModel making it easy to test ViewModels. Visual Studio (even Express versions) provides tools for testing. A couple of test methods included with the Test project give a basic idea of how testing can go.

5. Conclusion

Hopefully this article explained the usage of MVVM pattern on Windows Phone. Again, the code is available on GitHub, feel free to ask questions and/or leave comments

UPDATE 3/16/2014:

I updated the code in the repository to include a technique where a Text propery (or another one for that matter) can be used as a CommandParameter. See the code for full example, but in short, here is what you need to do:

In the View, I added a TextBox, gave it an x:Name property of "typeSomethingHere" (that's the second named control on the entire page). Then I added a Button, and I assigned the following properties to it besides Content and position on the page:

Command="{Binding DisplayInputWithoutAdditionalPropertyCommand}"
CommandParameter="{Binding ElementName=typeSomethingHere, Path=Text}"
The Command property is just as usual, but the CommandParameter property shows the beauty and flexibility of XAML, it grabs the Text property from the TextBox.

The rest are details, I create a string property ShowWhatWasTyped and it displays what was typed.

What's the bottom line here? I could have bound the Text property of a typeSomethingHere TextBox and use it to get text, but instead I taught the button to grab Text directly from the TextBox and pass it to the ViewModel. This works well only if you need to pass one value into a method quickly. You can, of course, use other properties of the ViewModel in the method.


Friday, February 21, 2014

Some notes on Angular.js

I have almost finished (read: abandoned) a project using Angular.js and here are some notes of little things that I would like to keep here so that I know where to find them next time.

This code snippet changes CSS class depending on the variable state:
ng-class="{CSSClassName: scopeVariable1 == scopeVariable2}"

The following regular expression finds the use of all scope variables that does not start with the letter "s":
\$scope\.[^s]+


Let's say there is a keyboard event, and the code needs to know what key was pressed. The following statement will provide the keycode to the function:
... ng-keypress="yourEventName($event.keyCode, otherArgsIfAny)" ...


Also, gotta remember that in JavaScript, when a variable's value is 'null', it means that there is such variable, but it has no value; when value is 'undefined' it means that there is no such variable.

In JavaScript, only the getMonth() function is zero-based (so December is month number 11), all other methods to get elements of a date are 1-based. To get year, use the getFullYear() function.

A new Date can be instantiated from milliseconds. For example:


var today = new Date(); //gets the date and time at the moment
var milliSec = Date.now(); //gets the number of milliseconds since epoch
//to reconstruct the date from millisec, just do this:
var someDate = new Date(millisec);


ng-show/ng-hide directives are pretty awesome to show/hide content:
...ng-show="oneVariable == anotherVariable"...
Or a function can be plugged in or a field or a string (if it is empty, then it would return false, otherwise -- true) or whatever else returns a boolean after evaluation.

Ordering a collection using Angular.js seems to be tricky. First of all, it only sorts arrays as of now. I had an array of object literals like so:
$scope.data = [{one:'one',two:'two'},{one:'three',two:'four'},{one:'five',two:'six'}];

and this sort expression worked for me:
<div ng-repeat = "a in data|orderBy:['one']">{{a}}</div>


You can access the ordinal number of the variable from within ngRepeat directive this way:
{{$index}}
Read more about it on Angular.js docs site.

The statement above becomes useful, if the app needs to convert an array into a comma- (or other delimiter) separated string. Here is a way to do it:
<div ng-repeat="a in itemCollection">
  {{a.someProperty}}
  <span ng-show="$index < itemCollection.length - 1">, </span>
  <span ng-show="$index >= itemCollection.length -1">. </span>
</div>
Let's say itemCollection has 3 items. $index is a 0-based variable, so for the first two items ($index is 0 and 1 and both times is less than three, so the span with a comma will be shown and the span with a period will be hidden. Then, on the last item $index equals to 2, which is >= to the (itemCollection.length-1), so the span with a comma will be hidden and the span with a dot will show up.

Wednesday, February 19, 2014

Select all text in TextBox using C#

Here is what worked for me today:
    txtContent.Focus();
    txtContent.SelectionLength = txtContent.Text.Length;
It does not work if the TextBox does not have focus. There are other solutions, but this one is quick and easy.

Friday, February 14, 2014

JavaScript: convert milliseconds to a date

Pretty easy, as it turns out:
  var dt = new Date(milliseconds);


And then one can use the standard Date methods available here. JSFiddle.

Monday, January 20, 2014

System.Windows.Control.ListBox does not scroll

An interesting one today. My ListBox would not scroll, and after looking into all usual suspects it still would not work. Turns out that the offender was the Grid, containing the ListBox. Here is XAML:
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <StackPanel Orientation="Horizontal">
                ...
            </StackPanel>            
           
            <ListBox ItemsSource="{Binding}" Grid.Row="1">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Description}" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>

My ListBox has a bunch of items and it does not scroll, even though there is no StackPanel in the DataTemplate. But, if I change the RowDefinition on the second row to say
                <RowDefinition Height="*" />

Then it scrolls just fine.

Friday, January 10, 2014

Initial git setup for a local project

Git is a great version control system available for free for private use. It is easy and very efficient. There is a short free book that explains the basics. Here is my short take on how to set up a git project locally (assuming that Git is already installed in the system.)

Open up the command shell and navigate to the root folder of the project. Then, issue the following commands (all comments come after the "#" mark):

  git init #initialize a git repository here
  notepad .git/info/exclude #optional step, here you can exclude files or folders that need no tracking
  #notepad will open with the document where you can type in values. 
  #If nothing needs to be excluded, just close the file.
  #to exclude a folder, mark it as so: bin/
  #to exclude all files with extension "sap", type in *sap
  git add . #to add all files recursively
  git status #(optional)see the files that will be committed.
  git commit -m "initial version" #commit with message "initial version"
  git log #check what's committed



Update from Feb 28, 2014: Here is another way to set up git locally, the difference between the script above is that the excluded files will be tracked by ".gitignore" file rather than "exclude" file. For sample of .gitignore files, check out this GitHub repository: github/gitignore, there are plenty of examples there for all kinds of programming projects. Here is the script:

  git init #initialize a git repository here, make sure you have a .gitignore file in the root folder of your project
  git add .gitignore #(optional)create or add a file that specifies which file(types) and/or folders to ignore
  git commit -m "Added .gitignore" #optional if you did not add .gitignore file
  git add . #to add all files recursively
  git status #(optional) see the files that will be committed.
  git commit -m "initial version" #commit with message "initial version"
  git log #check what's committed

And the first commit is done. It's that easy. To utilize tags, branching/merging, and other features of git that make it so good, read the book. The next logical step for the local repository is to create a distributed repository online and upload your code there. Bitbucket or GitHub are a places to start looking around.


Thursday, January 9, 2014

Monday, January 6, 2014

Karma, Angular.JS "Module is not available!" error

I was troubleshooting "Module '{0}' is not available!" error while testing an Angular.js app with karma and it got me puzzled quite a bit. Worst of all -- Google was not helpful (which clearly indicated that the problem is at my end). This url: http://docs.angularjs.org/error/$injector:nomod did not help either. My problem was that I forgot to include my controller js file into the files: [] array in karma configuration. Doh!

C# display integer in binary format

I was trying to understand an algorithm in this post here and it helped to visualize integers in binary format. A bit of Googling showed exactly how to do that:
    Convert.ToString(value, 2);

Monday, December 23, 2013

Draw a dot on HTML canvas

A helpful way to debug HTML canvas while doing a lot of translations, transformations, and so on.

      context.fillRect(0, 0, 2, 2);

This line prints a tiny rectangle at the point of zero coordinates.

Wednesday, December 11, 2013

MVVM Controls inside ListBox (ItemsControl) not firing

Scenario: you built an app using something that more or less closely resembles the MVVM approach that I described earlier, and you have a data control with a nested control that must execute some command. Here is how it might look:

//YourViewModel.cs:
private DelegateCommand yourCommand;

public YourPageConstructor()
{
  yourCommand = new DelegateCommand(this.YourMethod);
  ...
}

private void YourMethod(object obj)
{
  ...//do something here
}

public ICommand YourCommand { get { return yourCommand; } }

//yourPage.xaml.cs:
public yourPage()
{
  InitializeComponent();
  this.DataContext = new YourViewModel();
}

//yourPage.xaml:
<ListBox x:Name="yourDataControl" ...>
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel>
        <Button Command="{Binding YourCommand}" Content="YourItems" ... />
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>



You go to test your page, but your command is not firing. When you set a breakpoint at the "public ICommand YourCommand ..." line, you see that it is not being hit when the page loads. What's happening?

The thing is, your command should be a part of the collection that the ListBox is bound to for the ListBox to see (and execute it). Your command lives in your ViewModel, while the ListBox is bound to a collection. What to do? Bind your command in the following way:

//yourPage.xaml, add an x:Name attribute to the content of the opening PhoneApplicationPage tag:
<phone:PhoneApplicationPage
    x:Class="YourProjectName.Views.yourPage"
    x:Name="nameYourXAMLPageName"
    ...>

//and then change the Button's binding:
<ListBox x:Name="yourDataControl" ...>
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel>
        <Button Command="{Binding ElementName=nameYourXAMLPageName, Path=DataContext.YourCommand}"
                   Content="{Binding YourItems}" ... />
     </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>
...


This way, we are not embedding the command into the collection bound to ListBox, but rather, let the ListBox know where to find the command by providing the "address" of the current page's DataContext.


As usual, leave your thoughts in comments.

Monday, December 9, 2013

Today I learned: Unit testing using Visual Studio Express for Windows Phone

Visual Studio Express 2012 for Windows Phone has built-in support for Unit Testing. Here is the article on MSDN. Here is how to set it up (quickly). VS has to have at least update 2, and all you need to do is to add another project to your solution, choose "Windows Phone Unit Test App". Then write your unit tests and run them using the "TEST" menu on the top bar.

Now if only they allowed access to visualstudio.com for Windows Phone projects or made VS 2013 for Windows Phone available for download.

Wednesday, November 27, 2013

Error HRESULT E_FAIL has been returned from a call to a COM component error on Windows Phone


Summary:

  1. In your App.xaml.cs "Application_UnhandledException" method, check out the error contained in the e argument
  2. Mine mentioned the error in MeasureOverride method, so more than likely something was wrong with XAML
  3. My error happened because I 1) misspelled converter key and 2) declared converter as a resource after the declaration for the DataTemplate that used it

Long version:

I am working on a Windows Phone app. Many developers face this: you code, everything works fine. Then you change a couple of things and boom! you get a cryptic error message. In my case, the phone app kept hitting this code without no apparent reason:

        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
                System.Diagnostics.Debugger.Break();
            }
        }

I hovered my mouse cursor over the e argument of the method, and I got the following information:

MS.Internal.WrappedException: Error HRESULT E_FAIL has been returned from a call to a COM component. ---> System.Exception: Error HRESULT E_FAIL has been returned from a call to a COM component.
   at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
   at MS.Internal.XcpImports.UIElement_Measure_WithDesiredSize(UIElement element, Size availableSize)
   at System.Windows.UIElement.Measure_WithDesiredSize(Size availableSize)
   at System.Windows.Controls.VirtualizingStackPanel.MeasureChild(UIElement child, Size layoutSlotSize)
   at System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint)
   at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight)
   --- End of inner exception stack trace ---}

After a closer look, I noticed that the code mentions MeasureOverride method. I immediately turned to my last XAML document that I edited. Lo and behold, one of the lines was highlighted blue. I added a Converter to one of the values, and I misspelled the Key parameter inside the element. I fixed the typo and voila! same error. Here is an important detail about my scenario: I have a page with resources. I use a converter within a DataTemplate resource declaration. I also declared my local converter resource after the DataTemplate (that uses it). My error kept occuring (now) because I use a resource before I declared it. I changed my page to the following (just an idea):


<phone:PhoneApplicationPage.Resources>
  <local:myConverter x:Key="...
  <DataTemplate x:Key="...
    ...
  </DataTemplate
</phone:PhoneApplicationPage.Resources>

And everything started working.

Tuesday, November 26, 2013

Sunday, October 20, 2013

Joining multiple tables in MS Access

The syntax is tricky and I do it every once in a while and look it up every time (because the SQL errors in MS Access are far from being user-friendly). This site here has the general idea. But the details are below:

SELECT a.AField, b.BField, c.CField
FROM TableA AS a INNER JOIN (TableB AS b INNER JOIN TableC AS c ON b.BKey = c.BForeignKey)
ON a.AKey = b.BForeignKey

And, by the way:

TableB AS b INNER JOIN TableC AS c ON b.BKey = c.BForeignKey AND b.BField2 = 'someValue' AND c.CField2 = 'someValue'

join condition is not supported in Access, you have to put the join by some value in the table condition into the WHERE clause:

TableB AS b INNER JOIN TableC AS c ON b.BKey = c.BForeignKey 
...
WHERE b.BField2 = 'someValue' AND c.CField2 = 'someValue'