Showing posts with label Culture. Show all posts
Showing posts with label Culture. Show all posts

Tuesday, October 4, 2016

Asking Questions Shows Strength, Not Weakness

Our development culture has an element that I would like to eliminate: a fear of showing weakness. (There are other things I would like to eliminate as well, but this is the one I'm going to talk about today.)
Asking Questions Shows Strength, Not Weakness
There are some environments where people are afraid to ask questions from other members of their team. The reason for this fear is the response. Either the question is treated as a "stupid question", or the response is condescending ("I can't believe you don't know this"), or the person answering the question takes it as an opportunity to show off ("Let me demonstrate how much smarter I am than you").

I was extremely fortunate that the team I "grew up" with was not like this. But I have seen these teams personally, and I have talked to many developers who have been in these environments.

Why Now?
This is a topic that has been on my mind quite a bit. But it really came to the front of my mind this past week. I did several talks, including a user group, a workshop, and 2 code camp sessions. At least two times, when someone asked a question, they prefaced it with "This is probably a stupid question, but..."

The reason to preface a question like this is because we're really saying, "I'm not normally this weak, but..."

Before answering, I always say, "There are no stupid questions." We are trying to learn something new. New things don't always make sense the first time. We often need some clarification to really grasp the topic.

On top of that, we all have different histories, different experiences, different backgrounds. That means that we will have questions that are based on our own experiences. My questions will be different from your questions just because we have different experiences.

You're Not the Only One
Unfortunately, we have a fear of asking questions built in. When we look around, we see a lot of other people who are *not* asking questions. So they all must understand things, and I'm the only who who doesn't get it.

But in reality, we don't know what other people are thinking. We are comparing our insides (what I'm thinking and understanding / not understanding) with everyone else's outsides. We don't actually know if they understand it or not; we're making assumptions based on an invalid comparison. (BTW, This is exactly the same problem that leads to Impostor Syndrome. Scott Hanselman has a good article for devs: I'm a phony. Are you?)

When someone asks a question, I know that they aren't the only one with that question. How do I know? Because I do the exact same talks over and over again. And I will get the same questions over and over again. (As a side note, I'll add material to my talks to try to clarify and eliminate these questions where I can, but sometimes it's difficult.)

When someone asks me a question during a talk (or later in an email), it will often turn into a blog article. First because I don't always have time (or the knowledge) to go into detail during the talk. And second because I know that there are other people who have the same question.

Eliminating Fear
It's important that we eliminate this fear in our environment. Developers should be free to ask questions about things they don't know. It does not show weakness, it shows strength.
Without Questions, No Learning Takes Place
Our biggest assets in a team environment are the other team members. If the team members are afraid to ask questions, then no knowledge gets shared. This leads to a stagnant team. And in that situation, no one wins.

I have seen teams where the team members were afraid. Developers were afraid to ask questions because they didn't want to look weak. Developers were afraid to give answers because if they shared what they knew, they would be less vital to the team. These teams never succeeded. The team members were frustrated, discontent, and without hope. I really wish that I could have done something to change their environment, but it was built in to their entire political culture at the management level.

Breaking the Cycle
There are two things we can do to break this cycle.

1. Ask questions when you need help.
I would suggest doing some due diligence first. I spend some time researching the topic to see what I can find in documentation or forums. But I'll eventually get to the point where I can't get the answer on my own. At that point, I ask a question.

Some teams have a rule: If you spend more than 15 minutes trying to figure something out, you *must* ask for help. (There's usually a corollary that you must spend 15 minutes trying to figure something out for yourself *before* you ask for help. This is to encourage people to be an active part of learning rather than simply letting someone else do the work for them.)

2. Answer questions, and be supportive when you do.
When someone comes to you with a question, answer it. If you don't know the answer, help them find it or refer them to someone who might know. During this process, be supportive. Never act like the question is a stupid question. Don't take the opportunity to show off how smart you are. Make sure you answer the question in such a way that the person would be comfortable asking again in the future.

You Don't Know Everything
Here's a reminder: You don't know everything. And here's another reminder: No one else does, either.

It's okay to ask for help. It's okay to ask when you don't understand something. It's okay to ask for other resources that you can look at. This doesn't show weakness; it shows strength.
When we ask a question...
We are saying that we are interested in learning something new.
We are saying that we are not content with what we already know.
We are saying that we want to move forward.
Change the Culture
I'd really like to see a change of culture in our industry. I would love it if no one was afraid to ask for help. I'm not quite sure what needs to be done to change that. I'm going to encourage people to ask for help when they need it (Don't Be Afraid to Show What You Don't Know) and to help people who do ask for help (Help Those Behind You).

If you're stuck in an environment that doesn't encourage this, you have two options: Change your job or change your job.

If you can change the culture where you work, that's awesome. And all of your other team members will benefit from that. But if you can't change the culture, you need to make sure that you take care of yourself. In those instances, it might be best to leave and find a more productive environment.

Above all else, move forward. When we ask questions, we have the opportunity to learn something new. We can't control the response. But we can find the people who are happy to help us. There are lots of them out there.

Happy Coding!

Sunday, July 7, 2013

Changing Culture in WPF

I know my blog has been a bit empty over the last 6 weeks or so.  I've been working heavily on my C# Interfaces course for Pluralsight which released last week.  So now it's time to catch up on some articles that I've been intending to write.

This time around, we'll look at a bit of a hack that makes changing the culture in a running WPF application a bit easier than the majority of the solutions out there.  The sample project can be downloaded here: http://www.jeremybytes.com/Downloads.aspx#WPFCC.

Using the Machine Culture is Easy
.NET provides us a fairly straightforward way to support different languages and cultures in our applications. By default, our applications use the culture for the machine that they run on.  This means that if we provide resource files with different strings (or images or whatever) that are appropriate for a language, we get the behavior basically for free.

For example, we can provide a resource string in a resx file:


We have resource files set up for "en-US", "en-GB", and "en-AU":


Then in our XAML code, we just need to reference that resource string rather than providing a hard-coded string:


Notice that our "Text" property of this TextBlock references the static "Greeting" string resource.  So, when our application runs, it will automatically get the culture-specific value.

Here's the output:


And we can see "Howdy, Y'all!" is used in our TextBlock.  If our machine is set to a different culture, then we would get that culture-specific string (or the default culture if it's not available).

Note: This isn't a tutorial on how to localize your application, so you'll need to dig into that yourself.  We're just getting the basics in place so we can look at the "hack".

[Update Jan 2014: If you do want to learn how to localize an application in .NET, you can check out my Introduction to Localization and Globalization in .NET course available on Pluralsight.]

Changing the Culture is Hard
So, we've seen how easy it is to use the machine culture.  And, in fact, it's not hard to put in a custom culture (different from the machine) as the application is starting up.  But if we want to change the culture while the application is running, we run into a bit of a problem.

The "free" behavior that we get above (culture-specific resource strings from a file) only happens when the WPF window is being created.  This means that even if we change the culture of our thread while our application is running, the open windows will continue to use the already-bound resource strings -- no automatic updates.

The Scenario
The first question you might ask is "Why do we want to change culture in a running app?"  Well, I ran across this issue while helping a friend working on a project.  He was building a kiosk application in WPF that needed to support multiple languages.  The idea is that the user would walk up to the kiosk, press the button for the language they wanted, and then go from there.

If you cruise the internet, you will come across some interesting solutions.  Some people have built libraries where you call a method to rebind all of the resources of an open window.  I'm not a big fan of this solution just because it seems overly complicated.  And some of the libraries required you to put an attached property on all of the UI controls.

The most basic recommendation to change the culture of your application is to shut down and restart the app.  The idea behind this is that you update a configuration file with the new culture that you want.  Then you restart the application (which is never as easy as it sounds).  When the app starts up, it uses the new culture from configuration.

The "restart" solution sounded like the better solution of these two, but then I had a kind of crazy idea.

The Application MainWindow Property
In my sample code for my session on Dependency Injection (Dependency Injection: A Practical Introduction), I manually create the MainWindow for a WPF application.

Here's what the simplified code looks like (from App.xaml.cs):


The Application.Current.MainWindow is a property on our application that tells us what the main window is.  When the main window is closed, the application itself shuts down.  In this example, we create a new instance of the MainWindow class (which is defined by MainWindow.xaml) and then assign it to the MainWindow property of the application.  Then we Show the MainWindow.

The effect of this is that the MainWindow class is shown.  And when it is closed, the application shuts down.

So, I started to wonder if we could hack around with the MainWindow property a little bit so that we could simply create a new window (with a different culture) rather than shutting down the entire application.

The Hack: Resetting the Main Window
In the App.xaml.cs file, I added a new static method that would swap out the main window of the application.  Here's the code:


Let's step through this.

First, we set the CurrentCulture and the CurrentUICulture for the current thread.  The CurrentCulture defines the culture that the thread operates on.  The CurrentUICulture determines which resource file is going to be used.  For example, if we set the CurrentUICulture to a CultureInfo for "en-US", it will use the resources that are defined in the "Resources.en-US.resx" file (which gets translated into its own assembly/folder when the app is compiled).

We want to set the CurrentUICulture *before* we create the window.  This makes sure that the correct resources will be picked up.

After setting the culture, we create a local variable ("oldWindow") that points to the currently assigned MainWindow. We grab a reference so that we can programmatically close this window later.

Then we create a new MainWindow instance (again, this is coming from MainWindow.xaml).  This will be created with the resources for the new culture.  We assign it to the MainWindow property, and it becomes the main window for the application.

Next, we show the (new) MainWindow.

As a last step, we close the "old" window -- the one with the previous culture.  Since this is no longer the application's "MainWindow", it does not shut down the application.

The result is that the application will have a noticeable "window opening / window closing" effect, but we've managed to do this without shutting down the application.

The Results
Let's see the result in our sample application.  First, as we've seen, we have a TextBlock that uses the "Greeting" resource string.  In addition to that, we have 3 other text blocks.  In the code, we show the current culture, and we assign a date to display with both the short date format and the long date format.

Here's the code for that:


"displayDate.ToString("d")" gives us the short date format, which is "MM/dd/yyyy" in en-US.  "displayDate.ToString("D")" gives us the long date format, which is "dddd, MMMM dd, yyyy" in en-US.

We also have 3 buttons to change the culture.  Each button is similar.  Here's the click handler for the "US" button:


We can see that this calls the ChangeCulture method we looked at earlier.  This will re-create the window.  The constructor of the MainWindow calls "UpdateUIElements" to put the appropriate values in the text blocks.

Here are the outputs if we click each button in turn:




We can see that the "Greeting" text is different for each window.  Also, the short date and long date formats are appropriate to the culture.

As a bit of a humorous side note: I originally used today's date for the sample.  But since today is July 7, 2013, it would be very difficult to tell the difference between "07/07/2013" and "07/07/2013".

Wrap Up
So, this is a bit of a hack to re-create the main window for a WPF application.  But it is easier than restarting the application with new configuration values.  And with the kiosk scenario, it isn't a problem if we "reset" the entire application when the language is changed.

You might be able to use this same hack in a Windows Forms application (although getting to the application is a little less straight-forward).  It may also work in Silverlight by resetting the RootVisual (but I have not tried that).  I seriously doubt that it would work in a Windows 8 App Store app; this is also based on speculation since I have not done much with those types of apps.

Sometimes we come up with creative solutions to specific problems.  This one probably isn't very widely applicable, but it's fun to see what we can come up with nonetheless.

Happy Coding!