×

First time here?

You are looking at the most recent posts. You may also want to check out older archives. Please leave a comment, ask a question and consider subscribing to the latest posts via RSS or email. Thank you for visiting!

This is part 5 in a series on getting started with Silverlight.  To view the index to the series click hereYou can download the completed project files for this sample application in C# or Visual Basic.

In our previous step we added better data binding and saved some data to our isolated storage area.  Let’s start integrating some other controls to make our experience a little better.

AutoCompleteBox

Remember the history data we save every time a search term is used?  Let’s help our users search better, by providing them a history of their searches in the TextBox while they type.  We’re going to use a control from the Silverlight Toolkit to accomplish this, AutoCompleteBox.

To do this we need to add a reference to the System.Windows.Controls.Input assembly.  Then add an xmlns to your Search.xaml file:

   1: xmlns:input="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input"

With this in place, change the control named SearchTerm from TextBox to input:AutoCompleteBox:

   1: <input:AutoCompleteBox x:Name="SearchTerm" FontSize="14.667" Margin="0,0,10,0" Width="275"
   2:      IsTextCompletionEnabled="True" />

Now we need to provide data for the AutoCompleteBox.  In our Helper.cs class I added the following function:

   1: internal static string[] GetSearchTermHistory()
   2: {
   3:     List<string> searchHistory = new List<string>();
   4:  
   5:     foreach (var item in IsolatedStorageSettings.ApplicationSettings.Keys)
   6:     {
   7:         searchHistory.Add(item.ToString());
   8:     }
   9:  
  10:     return searchHistory.ToArray();
  11: }

Then in the Loaded event handler for Search.xaml.cs I added a call to Helper.GetSearchTermHistory():

   1: void Search_Loaded(object sender, RoutedEventArgs e)
   2: {
   3:     SearchResults.ItemsSource = pcv; // bind the DataGrid
   4:     _timer.Start(); // start the timer
   5:     SearchForTweetsEx(); // do the initial search
   6:     SearchTerm.ItemsSource = Helper.GetSearchTermHistory(); // populate autocomplete
   7: }

The result of which now is that when the application loads it will give the user some hinting while they search:

AutoCompleteBox in action

Helpful!

Adding our History view

Now that we have our search history, we can provide some data in a new view called History.xaml.  You should have already created this in the Views folder in a previous step, but if you haven’t, do so now (using the Silverlight Page item template).  Here we’ll want to show perhaps a simple list of all the terms.  We can easily do this using a ListBox in our XAML like this:

   1: <StackPanel>
   2:     <TextBlock x:Name="HeaderText" Style="{StaticResource HeaderTextStyle}" 
   3:                    Text="Serach Term History"/>
   4:     <ListBox x:Name="SearchTermHistory" />
   5: </StackPanel>

Then using a function we already have in Helper.cs, we can bind new data to the listbox like this in History.xaml.cs:

   1: protected override void OnNavigatedTo(NavigationEventArgs e)
   2: {
   3:     SearchTermHistory.ItemsSource = Helper.GetSearchTermHistory();
   4: }

So we are able to make re-use of a function to display a complete history of our terms:

History pane view

Adding some more navigation functionality

Now that we have a couple of views in the application, notice the navigation framework working.  You can navigate using the buttons, but also the back/forward browser buttons will also trigger the same functionality!

We can actually take this to the next level with the History view now.  In the ListBox I’m adding a SelectionChanged event handler:

   1: <ListBox x:Name="SearchTermHistory" SelectionChanged="SearchTermHistory_SelectionChanged" />

The function looks like this in History.xaml.cs:

   1: private void SearchTermHistory_SelectionChanged(object sender, SelectionChangedEventArgs e)
   2: {
   3:     this.NavigationService.Navigate(new Uri(string.Format("/Search/{0}", 
   4:             SearchTermHistory.SelectedItem.ToString()), UriKind.Relative));
   5: }

Notice the URI format I’m using?  It will end up being /Search/{term}.  We need to instruct our Navigation Frame in the application to map that accordingly.  Go back to MainPage.xaml and find the UriMapper content and add this line:

   1: <uriMapper:UriMapping Uri="/Search/{term}" MappedUri="/Views/Search.xaml?term={term}" />

Now we need to make our Search.xaml page understand this.  In Search.xaml.cs in the OnNavigatedTo I add this functionality:

   1: protected override void OnNavigatedTo(NavigationEventArgs e)
   2: {
   3:     if (this.NavigationContext.QueryString.ContainsKey("term"))
   4:     {
   5:         SearchTerm.Text = this.NavigationContext.QueryString["term"].ToString();
   6:         SearchForTweetsEx();
   7:     }
   8: }

Now when a user goes to the History page and selects an item, it automatically executes the search!

Summary

Integrating other controls and 3rd party controls like this will help define your user experience and hopefully provide an better experience for your users of the application.  There are a bunch of 3rd party control vendors producing great sets of components.  Visit my Silverlight Controls post for a list of them.  Be sure to check out the Silverlight Toolkit for others from Microsoft and a sample application showing all the controls.

We’ve got our application pretty well working, but the UI could use some more polish, in the next step in part 6 let’s show how we can better template this without affecting functionality.


This work is licensed under a Creative Commons Attribution By license.


10/10/2009 2:19 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Really helpfull tutorial!

Just to avoid that others run in the same trap too:
The mentioned additional line in the UriMapper content:

<uriMapper:UriMapping Uri="/Search/{term}" MappedUri="/Views/Search.xaml?term={term}" />

has to be inserted before

<uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/> !

Adding it after will end up with some navigation error messages, because the first matching Mapping is used.
Gravatar
11/3/2009 7:36 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Very Helpful.Thank you very much
11/10/2009 4:19 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Mark M - you didn't...thanks for calling me out -- it wasn't clear in this section: timheuer.com/.../...ted-part-3-accessing-data.aspx
11/10/2009 5:02 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Ok, now that that is straightended out :-) tks, but..
Each time I select an item in the history list an error is thrown Page not Found: "/Search/twitpic".

Why?

Below is code for selectionchanged event handler and the UriMapper and
private void SearchTermHistory_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.NavigationService.Navigate(new Uri(String.Format("/Search/{0}", SearchTermHistory.SelectedItem.ToString()), UriKind.Relative));
}

<navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}"
Source="/Search" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed">
<navigation:Frame.UriMapper>
<uriMapper:UriMapper>
<uriMapper:UriMapping Uri="" MappedUri="/Views/Search.xaml"/>
<uriMapper:UriMapping Uri="/{pageName}/{searchtext}" MappedUri="/Views/{pageName}?term={searchterm}"/>
<uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>
</uriMapper:UriMapper>
</navigation:Frame.UriMapper>
</navigation:Frame>
11/10/2009 5:21 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Mark M - I can't reproduce that error. I even changed my mapper to match yours. Feel free to send me your project offline to see if it fails on my box.
11/10/2009 6:06 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Hi Tim,

I would send you my project but I don't know how I can do this from here. Perhaps you could respond with instructions to my email address?
11/10/2009 6:10 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
nvn Tim. found it. Thanks again!
Gravatar
11/25/2009 9:06 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
I have the same problem as Marc M and I don't know how to fix the problem
11/25/2009 9:07 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Max -- Marc fixed his issue. Make sure that your UriMapping is corrrect and doesn't have any mismatched parameters.
Gravatar
11/25/2009 9:18 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
I found an error! Our uriMapper must be the first in the list. Here's the code:

<navigation:Frame.UriMapper>
<uriMapper:UriMapper>
<uriMapper:UriMapping
Uri="/Search/{term}"
MappedUri="/Views/Search.xaml?term={term}"/>
<uriMapper:UriMapping
Uri=""
MappedUri="/Views/Search.xaml"/>
<uriMapper:UriMapping
Uri="/{pageName}"
MappedUri="/Views/{pageName}.xaml"/>
</uriMapper:UriMapper>
</navigation:Frame.UriMapper>
My URI was the last and how I think its something catch before
Gravatar
1/11/2010 1:52 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Hello Tim. Excellent blog series! I played around with Silverlight in the past and was a bit disappointed with it's RAD capabilities and use in the Enterprise space. However, in light of the advancements since 1.0, I thought I'd give it another go. While I still don't believe the tools and data-binding capabilities are on par with other Microsoft development solutions, Silverlight has come a long way in a short period of time. Kudos to your team. I look forward to the future of Silverlight and quit possibly implementing a Silverlight Enterprise application in the Government space. Oh and BTW, good luck with that dive shop of yours... -Dan
1/17/2010 9:34 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Look at /Search/ onwards...

this.NavigationService.Navigate(new Uri(string.Format("/Search/{0}", SearchTermHistory.SelectedItem.ToString()), UriKind.Relative));

should be changed to

this.NavigationService.Navigate(new Uri(string.Format("/Search?term={0}", SearchTermHistory.SelectedItem.ToString()), UriKind.Relative));

Cheers, Christian
2/9/2010 1:38 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
I'm following along and everything works great so far, except that I'm getting the tweets repeated. In other words, when I search on a term the first time it works fine, then if I do nothing, and the timer event kicks off, the search is done again, and the results are added to the current list (sorted) so now at this point, I'm seeing doubles of everything. I'm not sure if there's something that I missed. Anyone else having this problem?
2/22/2010 9:07 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
I for some reason can not get any scroll bars, I don't understand why.

Thanks
3/16/2010 3:22 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
AutoCompleteBox and History not working
3/17/2010 6:15 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Hello Tim.
This function never works
foreach (var item in IsolatedStorageSettings.ApplicationSettings.Keys)
{
searchHistory.Add(item.ToString());
}
Thanks in advance!
3/17/2010 1:43 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
AutoCompleteBox. If i download the final project, that behavior not working.
Because "searchHistory.ToArray return ();" always empty.
3/23/2010 9:58 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Alex - download the completed solution to compare your code.

Peter -- yes even in an error OnReadCompleted should fire.
3/24/2010 8:39 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Hello Tim.
I've already download the completed solution and comparison made. But the completed solution source VB end CS, AutoCompleteBox not working also.
3/24/2010 8:52 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Alex, this is odd as I've got it working. Make sure the *web* project is the startup project.
3/29/2010 6:06 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Hello Tim.
I've done everything from start again. The result is the same. I've made comparison.
AutoCompleteBox and History not working.
I've already download the completed solution and only AutoCompleteBox not working.
Thanks in advance!
3/29/2010 6:08 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Alex - I'm not sure without looking at your system. Make sure the web project is the startup.
3/30/2010 11:41 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
To answer the questions about the duplicate tweets,
in OnReadCompleted, just after if(e.Error == null), add
searchResults.Clear();

The casing is important! That will clear the observable collection of existing items before adding new ones.

The amusing thing now is that my intellisense went buh bye after I added a reference to the controls. Still trying to fix that.
5/22/2010 11:00 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Can't get the AutoCompleteBox to work in SL4 and VS2010? It doesn't drop down when I type anything ... when I debug, the event Search_Loaded is only triggered for the 1st time...

Not sure why .. ran your sample also cannot ...

tested in both IE8 and Firefox 3.6.3 .. am using windows 7 32 bit

any help?
5/23/2010 7:55 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Alright got it working, basically you need to add this to Search.xaml.cs:-

protected override void OnNavigatedTo(NavigationEventArgs e)
{
SearchTerm.ItemsSource = Helper.GetSearchTermHistory();
}

Got it working now. Cool tutorials. Going next one.
6/4/2010 1:43 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
It appears that every time Search.aspx is navigated to, a new Search object is actually created, at least with my VS2010 + Silverlight 4. The net result is that:
1) When navigating back to the home page (i.e. the Search page), the search text box and the search results are cleared, because a new Search object is created (verified in debugger).
2) The old Search object is still in memory. I verified in debugger that its timer is still ticking with the old search term every 30 seconds. Even though the result is no longer displayed to the UI.
3) Because of (2) above, it ends up with multiple Search objects in memory, all with a ticking timer for every 30 seconds. I got a temp-ban from Twitter.com for querying too frequently after a while :)
I think this is an important aspect of how navigation works and you probably want to cover it in the tutorial. Thanks!
6/24/2010 12:08 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
silverlight
6/24/2010 10:46 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
I finished this step but only by replacing the style sheet I downloaded with from a previous step with the one downloaded with this step. Same XAML and same code behind, but initially the tweets would only display the Avatar and would not scroll.

Simply replacing the style sheet and whatever mumbo-jumbo was inside the style sheet made a huge difference.
6/28/2010 11:39 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Awesome tutorial...using the latest version of sl and VS2010 and yes I have to make a few adjustments but that's part of the learning process isnt (I take them as homeworks ;-)

keep up the good work...Silverlight is going to be big
8/15/2010 8:18 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Peter, your solution for avoiding duplicate results presents it's own problems. For example, let's say the timer's tick event is fired and some time after the BusyIndicator is set to busy but before the async read is complete and the BusyIndicator goes inactive, the user clicks the search button to initiate a new search (search term is different than the one for the currently active search). In your solution, since the BusyIndicator is active (or busy), the user's new search will not be executed at all. That may not be a big deal, but it might be annoying to the user to have to click the search button again. It could be said that the user shouldnt be clicking the search button if he/she sees a popup stating work is being done, but its possible that he/she can click the search button after the BusyIndicator is set, but before the popup is shown. Maybe this is an unlikely scenario but it's very possible. The real solution would be to not allow the user to click the search button while the BusyIndicator is active. To be clear, when you set the indicator to busy you should also disable the button ([buttonName].IsEnabled = false;)
8/18/2010 12:55 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Alternatively, in the XAML for the search page, you can put the layout inside of your BusyIndicator. When the BusyIndicator control's IsBusy property is set to 'True', all controls within it are disabled.
9/24/2010 5:51 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Awesome tutorial...using the latest version of sl and VS2010 and yes I have to make a few adjustments but that's part of the learning process isnt (I take them as homeworks ;-)

keep up the good work...Silverlight is going to be big
10/28/2010 2:14 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
I'm still really confuse how silver light works but I think I'm already starting to figure it out. Office Chairs
Gravatar
11/29/2010 3:35 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
I'm so amaze.. I found this silverlight alarm clock in one of the blogs I visited. The alarm is a video of a silverlight tutorial. Financial Articles
11/30/2010 4:06 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
I'm really excited in learning this new tool that I discovered.
Medical Assistant Jobs
12/6/2010 5:03 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Pretty cool post.It's really very nice and useful post.Thanks for sharing this with us!it’s my first visit.Pretty cool post.It's really very nice and useful post. | Hotels in Wisconsin Dells |Thanks for sharing this with us!it’s my first visit.
12/6/2010 10:44 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
I think I still need to watch more tutorial videos for this one. :D Praca
12/7/2010 2:27 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Thanks for sharing these stuffs, it sure will help us more in searching..
Pittsburgh Chiropractors
12/8/2010 9:12 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Thanks for this great tutorial :)
Fredj @ vitre teintée
12/10/2010 8:09 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Many thanks for this tutorial. I didnt know that i can use Visual Basic - thats just perfect! Silverlight is the future...

George,
trace phone
12/15/2010 9:17 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Great tutorial. Gets me right the the visual basic section that I have been struggling through.

Best,
Susan
http://www.cheapsatellite.tv/
12/20/2010 1:37 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Silverlight is really a good way of learning visual basic aside from the fact that silver light is also as interesting as VB. Canvas Printers
1/5/2011 3:18 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Well I don't know how it actually works but I'm pretty sure that it's one of the best New Products that I have seen so far.
1/15/2011 7:13 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
I'm almost through the silverlight tutorials and wanted to say thanks for doing them, they are really useful.

Lisa @ Marken Taschen - Currently I read through the whole blog since we are getting more involved in Silverlight right now. Thanks
1/20/2011 6:47 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Very interesting information thanks for the present Debra
2/22/2011 3:40 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
This blog really has all the things that I need to know about silverlight.
Supplements India
2/23/2011 5:40 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Where can I get the namespace System.Windows.Controls.Input? I already have downloaded the Silverlight Toolkit, but I couldn't find it there. Therefore, the line

xmlns:input="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input"

is underlined with a blue line ('The assembly "System.Windows.Controls.Input" could not be found. ...'). In my dispair, I selected System.Windows.Controls.Input.Toolkit, but that didn't work either. From where can I get the DLL for this?
2/23/2011 7:52 AM | # Problem with System.Windows.Controls.Input
I used the System.Windows.Controls.ComboBox instead of the AutoCompleteBox that I could not find or reference. It is perhaps a partial substitute for the not found AutoCompleteBox. Unfortuately, the IsEditable property of the ComboBox cannot be changed; it is set to false. Assigning true results in a runtime error. So, my ComboBox instance contains the previously entered words that I had added when the control was a TextBox. How is this ComboBox made editable? I couldn't find any hint concerning this control and my question.
2/24/2011 1:52 AM | # Solved the Input problem
Hello! I solved my problem with the System.Windows.Controls.Input namespace. For those who run into the same problem, here is the way how I solved it.

The hint how to solve was in the Source code of the installed Silverlight Toolkit. I opened it with "Start" -> "Microsoft Silverlight 4 Toolkit April 2010" -> "Source Code" that opens an Explorer window. Through the Microsoft search, I found that the folder C:\...\Toolkit\Apr10\Source\Source code.zip\Controls.Testing contains an AutoControlBox. I copied the folder to the Projects folder of Microsoft Visual Studio 2010 and opened this project. There, I could find the AutoControlBox. Under the project in the "Links" directory (in German "Verweise"), I saw that the System.Windows.Controls.Input namespace exists. I opened the properties to find the absolute path of this assembly. Then, the line

xmlns:input="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input"

... was no more underlined with the "blue line" - there were no errors left. :->

What to say? "Kaum macht mans richtig, dann gehts!"
2/24/2011 1:57 AM | # ad Solved the Input problem
It is of course the AutoCompleteBox and not an "AutoControlBox".
2/24/2011 10:26 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Thanks this post really opened my eyes. it is not only eye opening rather very beneficial for the people those who want to do something good in his life.
house for sale | discount electronics
3/23/2011 3:07 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
The history for searches is pretty cool. Users sometimes travel from one search to another and back to the first search. Silverlight is really amazing.
4/7/2011 10:22 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Jede Poolabdeckung wird nach Maß und individuell nach Ihren Wünschen gefertigt. Das
Modell, die Farbe und die Verglasung Ihrer Schwimmbadabdeckung werden von Ihnen
gewählt. Unser fachlich geschultes Personal berät Sie in allen Fragen gerne. Schwimmbadüberdachung
7/16/2011 6:21 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Im glad to see that people are actually writing about this issue in such a smart way, showing us all different sides to it. Youre a great blogger. Please keep it up. I cant wait to read whats next. healthy oatmeal chip cookies
7/17/2011 11:23 PM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
I am really enjoying reading your well written articles. I think you spend numerous effort and time updating your blog.I have bookmarked it and I am taking a look ahead to reading new articles.Domainsarama Domain Names
7/18/2011 5:03 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Want to eliminate the middle man and buy affordable used cars? Finding high quality used cars for sale by owner at Hertz Car Sales is just part of the used car shopping experience.
7/21/2011 5:34 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
This is the classic problem with anyone who wish to be a good blogger but simply do not have enough time for them to manage their blog properly.This is could be done, if they really want to make money with their blog, by appointing some good advertiser in internet to do the tasks for them.san diego solar
7/26/2011 1:44 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
I have read your blog it is very helpful for me. I want to say thanks to you. I have bookmark your site for future updates. Erotikshop
9/19/2011 8:51 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
I could tell how great you are in your field of interest. . I will bookmark your page and looking forward to read some more of your writings soon. You could relate in each detail very well. Thank you for spending a time on sharing such informative writings to us. Boldporn
7/20/2012 5:08 AM | # re: Getting started with Silverlight: Part 5 – Integrating other controls
Great article! I was looking for the information for long. Thanks for sharing!
11/1/2013 2:36 AM | # chiropractic lexington ky
At Elswick Chiropractic & Associates, we believe that treatment should combine leading edge technology and traditional, hands-on care. It should be an ongoing partnership between you and your doctor to help you recover from pain and to keep you healthy for life.
chiropractic lexington ky

 
Please add 3 and 4 and type the answer here:

DISCLAIMER:

The opinions/content expressed on this blog are provided "ASIS" with no warranties and are my own personal opinions/content (unless otherwise noted) and do not represent my employer's view in any way.