Creating User Feedback Forms
- Creating the User Feedback Form
- Sending the Data
- Defining Feedback Form Linkage
- Summary
Most developers understand the need to communicate with users during the formal design process. Many understand the necessity for continued communication as the application takes shape. However, developers often see the delivery of a completed application as the end of the road. After all, the application is debugged (mostly), meets the design criteria, and performs the designed taskno more communication is required.
Unfortunately, a flood of negative media, virus attacks, and disgruntled computer attacks tell a different story. Delivery of an application is the start of a new process, not the end of an existing one.
This article presents a case for including user feedback forms in your next application, and demonstrates how easy it can be to add such a form. Many developers see user feedback forms as an open invitation to criticism; hopefully, this article will change your mind.
User feedback forms are rare, yet I believe they should be standard in every application. Sure, you can find some Web sites with user feedback forms, but you usually don't see such forms with desktop applications.
There are three main reasons why most developers don't even want to talk about user feedback forms. First, many developers equate a user feedback form with a "kick me" sign. No one wants to receive endless criticism, yet many developers fear that this is precisely what a user feedback form will provide. Second, many developers feel that adding a user feedback form to the application would also add unwanted complexity and require too much development time. Finally, some developers expect that a user feedback form will only add to current application support costs.
Many of these concerns have developed the aura of an urban myth, and I can tell you from personal experience that they're unfounded. On a typical day, I receive about 65 support e-mail messages (I don't use a separate setup for user forms because there isn't a need to use one). Typically, 90% of the messages contain some type of request. About 8% contain noncritical comments. (Some e-mail messages contain both a request and a comment.) Each day, I get one or two messages that tell me I'm doing a good job; these e-mails help because they help me know what people like. Finally, two or three of the messages contain a critical complaint that I need to answer tactfully, but honestly. In short, most people use the feedback forms to provide the kind of input that I need, rather than the feared destructive criticism that no one wants to hear.
Most of my applications use the same generalized code for the user feedback form, so my cost for adding the form to an application is minimal. The form resides as a separate module that the user can activate from the Help menu. In many cases, the application also generates the form when it experiences an error. (I'll tell you more about actual uses later in the article.)
I also feel that the user feedback form pays for itself in a number of ways. For example, a user feedback form can alert me to an application problem that I might not find for days, months, or even years. Sometimes a user even provides a solution to the problem, which saves me the effort of looking for one. The user feedback form provides a positive way to deal with a negative problem. Changing the perception of the issue often results in better relations with the users and reduces the effect of potentially damaging negative application reviews. Finally, I receive user feedback when the information is fresh in the user's mind, rather than having to drag the information out during a subsequent support event. Consequently, it's my opinion that user feedback forms reduce support costs, not increase them.
Creating the User Feedback Form
It's relatively easy to think of user feedback form in generic terms. It's true that you can create a generic form, but a generic form won't help you troubleshoot an application. On the other hand, using a custom form for every need makes it harder to interpret the form and increases development time. It's normally best to rely on a combination form or to provide some form of flexibility in form construction.
The generic form includes the consistent elements used in all forms, such as the title of the report, and specialty items, such as a specific question. You could use this as a generic feedback form. However, when you want to send feedback for an error message, you need additional fields of data. Listing 1 shows how you can overcome this problem using multiple constructors.
Listing 1 A generic feedback form with multiple constructors
UserFeedback(void) { // Required for Windows Form support. InitializeComponent(); } UserFeedback(String *DialogTitle) { // Required for Windows Form support. InitializeComponent(); // Change the dialog box title. this->Text = DialogTitle; } // Holds the extra control information. String *Extras[]; UserFeedback(String *DialogTitle, String *AddedControls[]) { Int32 Counter; // Loop counter. Int32 ExtraPos; // Control definition. // Required for Windows Form support. InitializeComponent(); // Change the dialog box title. this->Text = DialogTitle; // Add the controls to the Extras array. Extras = AddedControls; ExtraPos = 0; // Add the controls to the dialog box. for (Counter = 0; Counter < Extras->Length / 3; Counter++) { // Create a new label. this->Controls->Add(new Label()); // Gain access to the label. Label *AddedLabel = static_cast<Label*>(this->Controls->get_Item( this->Controls->get_Count() - 1)); // Configure the label. AddedLabel->Text = Extras[ExtraPos]; ExtraPos++; AddedLabel->Top = 155 + ((Counter + 1) * 56); AddedLabel->Left = 8; // Create a new textbox. this->Controls->Add(new TextBox()); // Gain access to the textbox. TextBox *AddedText = static_cast<TextBox*>(this->Controls->get_Item( this->Controls->get_Count() - 1)); // Configure the textbox. AddedText->Width = 272; AddedText->Top = 179 + ((Counter + 1) * 56); AddedText->Left = 8; AddedText->Text = Extras[ExtraPos]; ExtraPos++; AddedText->ReadOnly = Convert::ToBoolean(Extras[ExtraPos]); ExtraPos++; } }
The first constructor contains just the default form. The second constructor adds a custom title, but doesn't change the controls. However, by the time you get to the third constructor, the form is adding controls based on input from an array. Each new control set requires three array entries. The first contains the text for the label associated with the textbox used for input. The second contains any textbox information. The third determines whether the user can modify the content of the textbox.
The code begins by adding a label. It then retrieves the Label object from the form and configures it. You must make sure that whatever scheme you use accounts for existing controls and allows more than one control addition. Notice that the code accesses the text for the Label object using the Text propertyjust as you normally would. Adding the TextBox object is about the same as adding the Label object. The only differences are the position of the TextBox on screen and the setting of the ReadOnly property. Figure 1 shows typical output from this constructor when using custom controls.
Figure 1 You can add any number of controls to this form.