CAIT: A COMPUTER ASSISTED INSTRUCTION TOOL Suzanne Louise Minton B.A., California State University, Sacramento, 2002 PROJECT Submitted in partial satisfaction of the requirements for the degree of MASTER OF SCIENCE in COMPUTER SCIENCE at CALIFORNIA STATE UNIVERSITY, SACRAMENTO FALL 2009 CAIT: A COMPUTER ASSISTED INSTRUCTION TOOL A Project by Suzanne Louise Minton Approved by: __________________________________, Committee Chair Dr. Cui Zhang __________________________________, Second Reader Professor Roxalie Jones ____________________________ Date ii Student: Suzanne Louise Minton I certify that this student has met the requirements for format contained in the University format manual, and that this project is suitable for shelving in the Library and credit is to be awarded for the Project. __________________________, Graduate Coordinator Dr. Cui Zhang Date Department of Computer Science iii ________________ Abstract of CAIT: A COMPUTER ASSISTED INSTRUCTION TOOL by Suzanne Louise Minton In this technology-centric age, the use of Computer Assisted Instruction (CAI) for distance learning is essential for a student's academic development. There is much research on how to build CAI to facilitate effective learning. However, the research results of the best CAI practices have not been fully implemented by available CAI tools. In addition, there is also a need for lightweight CAI tools. This Master's Project presents a tool called CAIT. The goal of this project is to develop a lightweight and decentralized CAI tool that teachers can use to help students understand the content from their classes at the students' own pace and own time. Using the templates provided by CAIT, teachers are able to enter lecture notes as various lessons and create quizzes that contain true/false, matching, and multiple-choice questions. To ensure that the proven CAI strategies for effective learning are employed, iv this tool provides teachers with various guidelines that they have to follow when they create their CAI materials. This project directly benefits teachers and students trying to include distance learning to complement coursework. __________________________________, Committee Chair Dr. Cui Zhang __________________________________ Date v ACKNOWLEDGEMENTS I would like to thank my Project Advisor, Dr. Cui Zhang, for her patience with me throughout this long process. She has made herself available to me often and always worked around my schedule. I thank her for not giving up on me. I would also like to thank my second reader, Roxalie Jones. She continuously encouraged me to finish this project. With her gentle prodding, I made it through! To my husband, David Risso, I owe gratitude for giving me the space and love that I needed to get the work done. Without the loving “nagging” from my Mom, Candy Minton, my mother-in-law, Roberta Risso, and my sisters, Gina and Heather Minton, I would have given up long ago. A very special thanks goes to my Dad, Jim Minton. I will never be able to fully understand or match the depth of your patience, which makes me appreciate it that much more. vi TABLE OF CONTENTS Acknowledgements……………………………………………………………...… vi Lists of Tables……………………………………………………………………… ix Lists of Figures…………………………………………………………………….. x Chapter 1 2 3 INTRODUCTION…………………………………………………………. 1 1.1 Motivation………………………………………………….. 1 1.2 Project Overview…………………………………………... 2 1.3 Expected Expertise of Intended Readers…………………... 3 1.4 Software Specification……………………………………... 3 BACKGROUND AND RELATED WORK…………………………….... 5 2.1 Background………………………………………………... 5 2.2 Best Practices for Lessons…………………………………. 5 2.3 Best Practices for Quizzes…………………………………. 7 2.4 Related Work………………………………………………. 9 DESIGN…………………………………………………………………… 11 3.1 Overview of Design………………………………………... 11 3.2 Use-case Diagram………………………………………….. 11 3.3 Class Diagram……………………………………………… 15 3.4 Database Diagram………………………………………….. 17 vii 3.5 4 5 6 Architectural Model............................................................... 18 GUI DESIGN AND USER GUIDE………………………………………. 21 4.1 Login and Menus…………………………………………... 21 4.2 Lessons…………………………………………………….. 25 4.3 Quizzes…………………………………………………….. 35 APPLICATION…………………………………………………………… 44 5.1 Real-World Trial of Application…………………………… 44 5.2 Instructor’s Perspective…………………………………….. 44 5.3 Student’s Perspective………………………………………. 45 CONCLUSION AND FUTURE WORK…………………………………. 48 6.1 Conclusion…………………………………………………. 48 6.2 Future Work………………………………………………... 48 Appendix Source Code in C#.................................................................................. 50 References………………………………………………………………………….. 127 viii LIST OF TABLES 1. Table 5.1 Results of Questionnaire………………………………………… 47 ix LIST OF FIGURES 1. Figure 3.1 Use Case Diagram for CAIT…………………………………… 12 2. Figure 3.2 Class Diagram for CAIT……………………………………….. 16 3. Figure 3.3 Database Diagram for CAIT…………………………………… 18 4. Figure 3.4 Architectural Model for CAIT…………………………………. 20 5. Figure 4.1 Login Screen……………………………………………………. 21 6. Figure 4.2 Main Menu (Lessons Tab)………………………………………22 7. Figure 4.3 Main Menu (Title Pages Tab)………………………………….. 23 8. Figure 4.4 Main Menu (Quizzes Tab)………………………………………24 9. Figure 4.5 New Lesson Title………………………………………………. 25 10. Figure 4.6 New Lesson…………………………………………………….. 26 11. Figure 4.7 Add Attachment……………………………………………….. 27 12. Figure 4.8 Edit Lesson…………………………………………………….. 28 13. Figure 4.9 Delete Lesson…………………………………………………... 29 14. Figure 4.10 View Lesson…………………………………………………... 30 15. Figure 4.11 Lesson Status………………………………………………….. 31 16. Figure 4.12 Change Lesson Title…………………………………………... 32 17. Figure 4.13 Change Lesson Order…………………………………………. 33 18. Figure 4.14 Edit Title Page………………………………………………… 34 19. Figure 4.15 Edit Quiz………………………………………………………. 35 x 20. Figure 4.16 Add Question (True/False)……………………………………. 36 21. Figure 4.17 Add Question (Match)………………………………………… 38 22. Figure 4.18 Add Question (Multiple Choice)……………………………… 40 23. Figure 4.19 Take Quiz (Multiple Choice Question)……………………….. 41 24. Figure 4.20 Take Quiz (Match Question)…………………………………. 42 25. Figure 4.21 Take Quiz (True/False Question)……………………………... 43 26. Figure 5.1 Questionnaire on the Use of CAIT…………………………….. 46 xi 1 Chapter 1 INTRODUCTION 1.1 Motivation In today’s computer-oriented society, it is important for teachers to provide their students with distance-learning tools to complement the in-class lessons. Students using Computer Based Instructional materials have mastered the objectives of the curriculum more effectively than a control group of students who did not utilize computer instruction [1]. Another concern for teachers is how to present teaching material without having to know too much about technology. Most teachers, with perhaps the exception of those in the area of technology, have minimal knowledge of designing Computer Assisted Instruction (CAI) tutorials for their students’ use. There is a need for a quick lightweight tool that can be used to create and present reading assignments and tutorials in a Windows environment, along with the creation and presentation of associated tests or quizzes. The tool should be easy to use and present a wizard to allow the entering of both lecture notes and quiz material. There has been considerable research into how CAI materials should be presented. The look and feel of the tool is almost as important as the contents of the tutorial. However a problem arises when trying to find such a tool. Most available tools have many options to choose from and require much set-up. Teachers need a tool to help them easily prepare out-of-classroom tutorials and quizzes. They need a tool that provides feedback to students to ensure that they are learning the material. The tool needs to present the class material in a self-paced, repeatable, and easy to use way. 2 1.2 Project Overview The goal of this project is to develop a lightweight course presentation tool that teachers can use to teach content from their lectures in a distance-learning environment. Their students are able to log into this application and go over the content that the teacher had discussed in class. The teacher is able to enter lecture notes as various lessons that the students can work through at their own pace. Quizzes that contain true/false, matching, and multiple-choice questions are available at the end of each section. To show various uses of the tool, the application includes a sample lesson and quiz on logical operators, a topic that is often included in beginning Computer Science classes. This lesson demonstrates the use of the tool and shows the many options that are available such as variable numbers of quiz questions and answers and examples of the various question styles. The development of this project used Software Development Life Cycles techniques. In particular, the Iterative Design Process has been used. This process starts with a simple implementation of a section of the software requirements and iteratively enhances and adds additional functional capabilities until the full system is implemented. Chapter 2 gives a brief description of the background, need, and guidelines for this project. It also outlines the justification for the research and implementation for this project while comparing it to current tools that are available. Chapter 3 details the design of the project. It studies the project’s architectural, detailed, and database models. The class diagram and database architecture are discussed. The GUI design is presented in 3 Chapter 4. This chapter uses various screen shots to illustrate how the software works. Chapter 5 presents an application of the CAIT project. CAIT was used in an actual classroom setting. The details of this application and the conclusions that were drawn from it are shown in this chapter. Chapter 6 concludes the project report and suggests venues for future work. 1.3 Expected Expertise of Intended Readers Although it is clearly stated that this project is to be used as a tutorial-designing tool for teachers with minimal experience in technology, there are some specific skills that the reader is expected to possess. These include basic computer capabilities, such as how to operate a mouse, how to open and close software applications, and how to navigate in a Windows environment. 1.4 Software Specification This project uses C#.NET 2005. C#.NET is supported in the following operating systems: Windows 2000, Windows 98, Windows 98 Second Edition, Windows ME, Windows NT, 4 Windows Server 2003 Service Pack 1 for Itanium-based Systems, Windows Server 2003 x64 editions, Windows Vista Business, Windows Vista Enterprise, Windows Vista Home Basic, Windows Vista Home Premium, Windows Vista Starter, Windows Vista Ultimate, Windows XP, and Windows XP Professional x64 Edition. The user will need to download .NET Framework Version 1.1 Redistributable Package if it is not already on the client machine. A free download of this framework is available at [2]. In order to get better performance, running the program on a computer with 700MHz CPU and up with 128MB memory and up is recommended. 5 Chapter 2 BACKGROUND AND RELATED WORK 2.1 Background There are obvious advantages to CAI. One such advantage is that the lessons and instruction materials can be viewed anywhere at anytime. Another benefit is that the instruction is self-paced and repeatable. In addition, the quizzes and problems are interactive which keeps the students’ attention for longer periods of time as compared to the one-way communication that reading text provides. The next two sections contain directions for instructors to make use of important user interface practices, how and when to give feedback to students, and other best practices for developing a CAI tool. 2.2 Best Practices for Lessons In order for CAI to be effective, certain objectives must be met—a considerable burden is placed upon instructors to skillfully and effectively present the lesson information. The lesson materials and information should be structured so that students are encouraged to practice and study until the desired level of knowledge and skill is achieved. The confirmation of the success or failure of an instructor’s efforts is measured by later evaluations of student learning [1]. Each CAIT lesson has the following attributes which are recommended for all computer tutorial programs: there is a title page which includes a statement describing the lesson, goals and objectives, and directions for running CAIT, there is a menu for 6 students to choose lessons from so that they have the ability to direct their lesson sequencing, and there is a way to exit the program from every page. The title page is important and should be crafted to motivate students. Long, complicated, or humorous text and graphics are found to be more annoying than helpful [3]. At the onset, instructors should clearly present the instructional objectives and let the students know what is expected. “Student performance has been shown to improve when the objectives and expectations are clearly known in advance” [1]. The instructor should try to provide clear, accurate, and concise directions. When instructors are inputting lessons, they should be sure to relate prior lessons and learning to the current lesson. The flow of lessons should be seamless. Instructors may find that the logical order of the lessons is not obvious from the outset. This is the main reason that CAIT allows instructors to change the order of lessons after entering them. Although instructors have the opportunity to order the lessons in the way they wish students to complete them, it is important that the students be able to self-direct their learning [3]. Students may find it more comfortable or convenient to choose the order in which lessons are attempted. Providing students with a menu of mini-lessons but giving them the ability to return to the main menu at any point is a very important concept of CAI [3]. This is why CAIT allows students to start with any lesson and they are not forced to follow the lessons in a certain way. One theory of CAI that is still debated is the effectiveness of pre-tests [1]. Although there are mixed reviews on the desirability of this lesson structure, CAIT has 7 provided the opportunity for this, by allowing students to access the quiz before and after reading and studying the lesson. Each lesson, or presentation, should present only one instructional concept at a time. The instructor should try to avoid presenting too much information at one time by trying to limit the lesson to no more than 23 lines of 40 characters per line [1]. In addition, graphics have been shown to help with long-term memory of both verbal and written knowledge. Color can enhance learning [1]. After each complete lesson, there should be questions for students to ensure that they understood the lesson. CAIT has built-in tools to help instructors meet the above goals. For instance, when instructors are entering a new lesson, or editing an old one, there is a graphical line across the top of the textbox to show how long 40 characters would be (see Figures 4.6 and 4.8). Attachments are available to go along with every lesson. Consequently instructors can use graphics to help explain a difficult concept. Also, instructors are encouraged to create a quiz after each lesson. 2.3 Best Practices for Quizzes Besides lessons being written and formatted correctly, the second most important attribute of a good Computer Assisted Instruction tool is a high-quality quiz and testing system. There are many best practices when it comes to quizzes and CAIT attempts to include them all. When writing a quiz, keep the following point in mind—“the most effective pedagogical methods are those which include all three of the important types of 8 questions” [1]. These are multiple-choice, matching, and true/false. CAIT allows instructors to enter all three of these types of questions and does not consider the quiz complete until there is at least one of each type. Multiple-choice questions help students retain information [1]. Students are more likely to remember this information when they see the correct answer in a list of similar choices and are asked to choose the best alternative among them. For this reason multiple-choice questions in CAIT must contain possible answers that are all seemingly valid, but distinguishable from each other, there must not be ambiguous choices and the wording must be stated in an active voice. The next type of question is a Matching question. This is where there is a list of items on the left-hand side of the page that must be matched to a set of items on the righthand side of the page. See Figures 4.17 and 4.20 for examples of this type of question. Matching questions help students visualize the correct answer [1]. The important points to remember when creating this type of question are: the question must measure the students’ ability to identify the relationship between a set of similar items, each of the items in each of the lists must be homogeneous, or similar to each other, and there are the same number of items in each list. A key tip to remember is that the items with more words should be in the list on the right-hand side of the page, not the left-hand side [3]. True or False questions reinforce factual statements [1]. Student must be able to identify whether a statement is correct or not. The guidelines for this type of question are: the statement must test the students’ recall or confirmation ability, the assertion must center on an important concept from the lesson, and it must be a fact, not an opinion. 9 Besides the types of questions presented to students, the quizzes must provide immediate and corrective feedback. Positive reinforcement is the best kind of feedback [1]. To supply this, instructors, if possible, should anticipate student errors and offer reasons why these might be good answers, but are incorrect. This anticipation helps without destroying interest and/or self esteem. It is often helpful to state why the answer was wrong, and then repeat the question with the correct answer [3]. CAIT has a space below each question where instructors must provide additional information about the answer, thus enforcing this best practice. 2.4 Related Work Three related projects were examined during the research portion of this Masters Project—MERLOT [4], Moodle [5], and WebCT [6]. These projects are discussed in the next few paragraphs. MERLOT uses peer-to-peer sharing of scholastic materials and requires the registration of these materials for any contributors of information. The information is then subject to reviews by fellow contributors and must be accepted by members of a faculty development support services group in order to be published [4]. This process ensures quality work, but it is cumbersome to many instructors who would prefer a lighter-weight tool. Moodle is a software package for producing Internet-based courses and web sites. It is known for its heavy system requirements. Moodle is a global development project designed to support a social constructionist framework of education. The approach that 10 Moodle uses towards education emphasizes “that learners (and not just teachers) can contribute to the educational experience in many ways” [5]. This creates a back and forth conversation for the students and instructor. While this is an admirable quality for a higher-education based tool, this is not the purpose of CAIT. WebCT is more focused on the professor and on course management. “It is an online proprietary virtual learning environment system that is sold to colleges and other institutions and used in many campuses for e-learning” [6]. WebCT allows instructors to use discussion boards, mail systems, and live chat, along with many other course management tools. This is very helpful to many instructors for organizing coursework and assisting students, but its focus is much broader than that of CAIT and is not specialized in providing a best practices environment for tutorials. 11 Chapter 3 DESIGN 3.1 Overview of Design This chapter shows the overall design of CAIT. It uses diagrams and models typically found in Unified Modeling Language (UML). UML is a language “used to specify, visualise, construct and document the artifacts of an object-oriented softwareintensive system under development. The UML represents a compilation of ‘best engineering practices’ which have proven successful in modelling large, complex systems.” [7] Presented in this chapter are: Class Diagram Use Case Diagram Database Diagram Architectural Model 3.2 Use-case Diagram Use-case diagrams are a useful way to help visualize the functionality of a software system. “Its purpose is to present a graphical overview of the functionality provided by a system in terms of actors, their goals (represented as use cases), and any dependencies between those use cases.” [8] 12 Add/Edit Lesson Update Lesson Status Add/Edit Quiz Create Title Page Add/Edit Question Attach a File Save Figure 3.1 Use-Case Diagram for CAIT The Use Case Scenarios below show different actions that an instructor or their students are able to complete using CAIT. The Use Case Scenarios outline typical user actions. Alternate Scenarios are used when a Use Case Scenario has more than one path that a user can take. An alternate scenario shows what will happen when the user takes that path. Use Case Scenario 1: Add Lesson 1) The user chooses to add a “New Lesson” and enters a lesson name. 2) If there is already a lesson with the same name, the user will be prompted for a different lesson name. 13 3) The user can enter text for the lesson and/or select to “Attach a File”. 4) After the user finishes with the lesson, they can “Save” the lesson. Alternate Scenario 1a shows what will happen if the user chose “Edit Lesson” in step 1 of Use Case Scenario 1 instead of choosing “New Lesson”. Alternate Scenario 1a at step 1 of Use Case Scenario 1: 1) Instead of selecting “New Lesson” the user can choose a previously saved lesson and select “Edit Lesson”. 2) The program will display the previously entered lessons and attachments. 3) User can proceed with step 3 of Use Case Scenario 1. Use Case Scenario 2: Add Quiz 1) The user chooses to add a “New Quiz” 2) The functionality to add a “New Question” is available. 3) True/False, Multiple Choice, and Match are all valid question types. The user selects the type to be constructed. 4) The user enters all of the data for the question which includes the question text, the answer, and additional information about the answer. 5) After the user finishes with the quiz, they can “Save” the quiz. 14 Alternate Scenario 2a shows what will happen if the user chose “Edit Quiz” in step 1 of Use Case Scenario 2 instead of choosing “New Quiz”. Alternate Scenario 2a at step 1 of Use Case Scenario 2: 1) Instead of selecting “New Quiz” the user can choose a previously saved lesson and select “Edit Quiz”. 2) The program will display the previously entered questions. 3) User can proceed with step 2 of Use Case Scenario 2. Alternate Scenario 2b shows what will happen if the user chose “Edit Question” in step 3 of Alternate Scenario 2a instead of choosing “New Question”. Alternate Scenario 2b at step 3 of Alternate Scenario 2a: 1) Instead of choosing to add a “New Question” the user can decide to change a previously entered question and select “Edit Question”. 2) The program displays the previously saved question. 3) User updates the question as desired. 4) User can then proceed with step 5 of Use Case Scenario 2. Use Case Scenario 3: Update Lesson Status 1) When the user wants to “Update Lesson Status”, the correct lesson is chosen and update lesson status is selected. 15 2) The requirements for a lesson using best practices are listed. 3) The user selects the criteria that have been met. 4) “Save” is chosen. Use Case Scenario 4: Create Title Page 1. One of the steps to building a good lesson is to create a title page. 2. The user selects “Create Title Page”. 3. All of the fields must be entered, thus creating a brief summary of lesson, goals and objectives, and special directions for this lesson. 4. The user then chooses “Save” to complete the title page. 3.3 Class Diagram A class diagram shows the relationships between the classes in an object-oriented program. The classes are depicted as boxes with two sections. The top section shows the attributes of the class, the bottom portion shows the class’s methods. Figure 3.1 shows the class diagram for CAIT. 16 MainMenu Login userType _____________ Login() 1 1 userType ____________ addEditQuiz() takeQuiz() deleteQuiz() addEditLesson() viewLesson() deleteLesson() changeLessonOrder() showLessonStatus showBestPractices() showHelpPage() refresh() logout() 1 m m m m LessonStatus TitlePageCreation AddEditLesson AddEditQuiz quizCreated examplesGiven goodExplanation oneConcept orderLessons titlePageCreated _____________ updateStatus() saveStatus() lessonID _____________ addSummary() addDirections() addGoals() saveTitlePage() ensureBestPracticeUsed() userType lessonID attachmentID _____________ addLesson() editLesson() saveAttachment() changeLessonOrder() saveLesson() ensureBestPracticeUsed() lessonID quizID questionNum _____________ addQuestion() editQuestion() deleteQuestion() changeQuestionOrder() saveQuestion() takeQuiz() saveQuiz() ensureBestPracticeUsed() 1 1 m Attachment attachmentType attachmentFile attachmentName _____________ browse() save() 1 1 FileManager _____________ openFile() viewFile() saveFile() Figure 3.2 Class Diagram for CAIT m AddQuestion quizQuestionID typeOfQuestion _____________ constructTFQues() constructMCQues() constructMatchQues() retrieveQuestion() validateQuestion() saveQuestion() ensureBestPracticeUsed() 17 3.4 Database Diagram A database diagram is also referred to as an entity-relationship diagram because it shows all of the entities in the database along with their relationships to each other. It visually displays the primary keys, the foreign keys, and any other field in the table that is required. In Figure 3.3, the database diagram for CAIT, the primary keys are denoted in bold and underlined with “PK” next to them, the foreign keys are displayed in bold with “FK1” next to them, and the required fields are displayed in bold without any notation next to them. 18 LoginInfo PK LoginInfoID LoginTime LoginUserType Lesson TitlePage PK TitlePageID FK1 LessonID LessonTitle Summary GoalsObjectives Directions Quiz PK LessonID Title QuizStatus LessonNumber LessonStatus PK LessonStatusID FK1 LessonID LessonName OrderLessons OneConcept GoodExplanation ExamplesUsed QuizCompleted TitlePageCompleted PK QuizID FK1 LessonID LessonTitle QuestionNumber QuestionText Answer TypeOfQuestion AnswerDescription Col1Text Col2Text PossAnswerA PossAnswerB PossAnswerC PossAnswerD Attachment PK AttachmentID FK1 LessonID LinkName LinkDescription Attachment Figure 3.3 Database Diagram for CAIT 3.5 Architectural Model The Architectural Model represents the overall system from the different viewpoints of various users of the system. According to the definition from Fact Guru, an architectural model shows “the logical breakdown [of the system] into subsystems, often shown using package diagrams” [9]. The package diagram used in the Architectural Models in Figure 3.4 are GUI, Teacher Control, Student Control, Lesson/Quiz Builder, Lesson/Quiz Viewer, Attachment Manager, and File Manager. 19 The GUI component captures user input and directs the user to the Teacher Control or the Student Control depending on their preference and permissions. Teacher Control determines whether the instructors want to add, edit or view a lesson or quiz. If add or edit is chosen, the instructors are directed to the Lesson/Quiz Builder. If view is chosen the instructors are directed to the Lesson/Quiz Viewer. Student Control determines which lesson or quiz the students wish to peruse and directs them to the Lesson/Quiz Viewer. The Lesson/Quiz Builder module allows the instructors to insert or edit lessons and quizzes. If editing, files will be fetched from the File Manager. If the instructors wish to add an attachment, they will be directed to the Attachment Manager. When finished, the lesson is written to the File Manager. Lesson/Quiz Viewer allows the user to access the lessons and quizzes. This component queries the File Manager to get the files needed to display the lesson or quiz. Attachments from the Attachment Manager can be sent to this component. Attachment Manager controls all aspects of the attachment system. It manages any files that the instructors wish to add to their lessons and later fetches the attachments from the File Manager and opens them for the Lesson/Quiz Viewer. File Manager controls all aspects of the file system. It saves the files that were created by the Lesson/Quiz Builder, sends files that were previously created to the Lesson/Quiz Builder for editing, and later displays the contents for the Lesson/Quiz Viewer. 20 Figure 3.4 Architectural Model for CAIT 21 Chapter 4 GUI DESIGN AND USER GUIDE 4.1 Login and Menus The GUI design and User’s Guide are shown in this chapter. All of the screenshots from the program are shown here along with descriptions explaining how to use each control. Figure 4.1 Login Screen The Login Screen (see Figure 4.1) is the first window that the CAIT user sees. In this window there are two radio buttons. The user must choose either the Instructor button or the Student button. If the Instructor button is selected, the user is required to supply a Password. There is a file included in the set-up folder that contains the password. 22 Figure 4.2 Main Menu (Lessons Tab) Figure 4.2 shows CAIT’s Main Menu window. If the Lessons tab is selected in this window, the user may choose from among the following buttons—New Lesson, Edit Lesson, Delete Lesson, View Lesson, View Lesson Status, Change Lesson Title, Change Lesson Order, and Take Quiz. The Refresh link, Logout link, and Exit link are available from this screen as well. The Refresh link will refresh the Lessons list. This link may be pushed if the user feels that the lesson list should be updated. The Logout link logs the user out of CAIT, in this way the instructors can re-login as a student and see what the students will see. The Exit link will close the application. The Best Practices link and the Help link are displayed at the bottom of the screen. The Best Practices link will open a Microsoft Word document that explains various practices that are recommended for CAI. The Help link will open this User’s Guide. 23 Figure 4.3 Main Menu (Title Pages Tab) Figure 4.3 shows the view of the Main Menu when the Title Pages tab is selected. From this view instructors may edit the title page by selecting the lesson from the Lessons list and clicking on the Edit Title Page button. Notice the links for Refresh, Logout, Exit, Best Practices, and Help are also available from this screen. 24 Figure 4.4 Main Menu (Quizzes Tab) Figure 4.4 shows CAIT’s Main Menu with the Quizzes tab selected. The user is given the option of selecting either the Edit Quiz button, or the button labeled Delete Quiz Contents. It is important to note that the list of quizzes is populated through the database’s lesson table so every lesson has a corresponding quiz. When the user elects to delete the quiz contents, only the questions from the quiz are deleted not the quiz itself. As before, the links for Refresh, Logout, Exit, Best Practices, and Help are available from this screen. 25 4.2 Lessons Figure 4.5 New Lesson Title When a user selects to create a New Lesson from the Main Menu Lessons Tab, (see figure 4.2), they will get a popup window asking them to input a lesson title. The lesson title must be alphanumeric and unique from all other lesson titles. They may choose to Continue which will take them to the New Lesson entry page (see Figure 4.6), or to Cancel, which will take them back to the Main Menu (see Figure 4.2) 26 Figure 4.6 New Lesson Users can enter new lessons by using CAIT’s New Lesson window (see Figure 4.6). The lesson text is entered in the Text window. Notice the line above the Text box that says, “40 chars (recommended length)”. This line will visually help instructors comply with the recommended best practice that the lesson length should be no longer than 40 characters long. Attachments may be added through the use of the Add button towards the bottom of the screen. The Delete button will delete the selected attachment and the View button will open the selected attachment. The Save button is used to save any entered text, the Save and Exit button will save the lesson and exit to the Main Menu (see Figure 4.2), and the Cancel button may be used to cancel the creation of a new lesson. 27 Figure 4.7 Add Attachment When the user chooses to add an attachment they will see the popup window in Figure 4.7. It requires a File Name, the Link Path, and the Link Description. The File Name should be a name that the instructors wish to display to the students. It does not have to match the actual file’s name. The Link Path can be populated by clicking on the Browse… button and navigating to the file to be added. This file can be a text file (i.e., any file with the extension .doc or .txt), image file (i.e., any file with the extension .bmp, .jpg, .gif, .pdf, .tif, .tiff, .or giff), or Excel file (i.e., any file with the extension .xls, or .xslt). The Link Description should be a brief description of what the students will find in the file. After choosing the file name, link path, and link description instructors may either Save the attachment or Cancel the addition of the attachment. 28 Figure 4.8 Edit Lesson Users can edit existing lessons by using CAIT’s Edit Lesson window, shown in Figure 4.8. The lesson Title is displayed in the Title window—note that the lesson Title cannot be changed or edited. The lesson text is displayed in the Text window and any desired editing may be performed in this window. The Save button is used to save any changed text, the Save and Exit button will save the lesson and exit to the Main Menu (see Figure 4.2), and the Cancel button may be used to cancel the changes to the lesson. 29 Figure 4.9 Delete Lesson The Delete Lesson popup window is displayed if the Delete Lesson button has been clicked, see Figure 4.9. The user should confirm the deletion of the lesson before continuing. Deleting the lesson also deletes any associated quiz, attachments, and title page. 30 Figure 4.10 View Lesson The View Lesson page (see Figure 4.10) is the page students will use to study a lesson. Instructors also have the option of seeing the lesson from this vantage point so that they can determine if this is what they want students to see. The only options on this page are to Open an attachment and to Close the lesson. 31 Figure 4.11 Lesson Status The Lesson Status page is a page that instructors can go to and see a list of the most important Best Practice requirements (see Figure 4.11). The Lesson Status page can be accessed through the Main Menu (see Figure 4.2). Instructors should read through the list and make a checkmark beside the requirements that they have completed. They can click the Save button to save their progress and come back to it at any time. They can click the Cancel button to cancel the updates. 32 Figure 4.12 Change Lesson Title Instructors wishing to change a lesson title, can click the Change Lesson Title button from the Main Menu (see Figure 4.2). From this screen (see Figure 4.12) they can enter the new title and click the Save New Title button. If they wish to cancel the update, they may click the Cancel button. 33 Figure 4.13 Change Lesson Order On the Change Lesson Order page (see Figure 4.13) instructors may change the order of the lessons. They should select the line from the grid that they want to change and then click either the Move Up or Move Down link. When they are finished they should click the Exit button. 34 Figure 4.14 Edit Title Page The Edit Title Page button can be accessed from the Main Menu (see Figure 4.3). On this page (see Figure 4.14) instructors should enter a Brief Summary of the Lesson, Goals and Objectives for the students, and Special Directions for this Lesson. This title page will be displayed to the students before the lesson is shown. According to CAI Best Practices, the students should know what each lesson is supposed to teach, what is expected to be accomplished after studying the lesson, and any special directions that the lesson requires. After the instructors have entered text in all of the fields they can Save their changes, or Cancel and return to the Main Menu. 35 4.3 Quizzes Figure 4.15 Edit Quiz Figure 4.15 shows CAIT’s Edit Quizzes page. It can be accessed through the Main Menu (see Figure 4.4) by clicking the Edit Quiz button. On this page, instructors can add, edit, delete, and change the order of quiz questions. The Lesson Name drop box allows instructors to switch between the different lessons’ quizzes. The Add Question button will take instructors to the Add Question page (see Figure 4.16). If the instructors wish to edit one of the previously entered questions, they should choose the question from the grid on the left and click the Edit Question button. This takes them to the Edit Question page which is the same as the Add Question page (see Figure 4.16) except that the fields are filled in with the previous data and only show the specific question that was chosen. The Delete Question button deletes the chosen question. After entering the questions if instructors wish to change the order of the questions, they should choose a question from the grid and choose either the Move Up or Move Down link. 36 Figure 4.16 Add Question (True/False) When the user clicks the Add Question button from the Edit Quiz page (see Figure 4.15), they are brought to the Add Question page, Figure 4.16. The Lesson Name and Question Number are displayed at the top of the page. Notice the tab choices on the main window. This is where instructors can choose the type of question they wish to enter: True/False, Match, or Multiple Choice. This screenshot shows the True/False question entry view. In the textbox next to Text instructors should enter the text for the question. They should either choose the True radio button or the False radio button depending on the correct answer to the question. Additional information about the answer should always be entered. This will help the students understand the correct answer and is a very important part of CAI Best Practices. At the bottom of the page instructor can choose to save the question (Save Question button), delete all of the information in the textboxes and start over (Reset button), cancel the addition of the question (Cancel Button), or finish adding questions and go back to the Edit Quiz page 37 (Finish Quiz). Please note that the Save Question button will take the user to the next question with the Question Number incremented by one. 38 Figure 4.17 Add Question (Match) Figure 4.17 shows the Match Question entry window. Notice the Match tab is selected. The first two fields that instructors should populate are the “Enter type of data in first column” and “Enter type of data in second column”. These should be filled with short descriptions of the data in the two columns. For example, if this was for a Botany class instructors might have a list of plant names in the first column and a list of plant types in the second. They would write “plant name” in the first textbox and “type of plant” in the second textbox. This would display the sentence “Please match the plant name to the type of plant” to the students. The textboxes under Column 1 could then be Elm, Rose, and Flannelbush and the textboxes under Column 2 could be shrub, tree, and flower. Under the Letter of Answer column, the textboxes should be B, C, A to correspond the correct answer in Column 2 to the plant name in Column 1. It is important to note that the number of entered textboxes 39 in each column must be the same. As before, the Save Question, Reset, Cancel, and Finish Quiz buttons are available at the bottom of the page. 40 Figure 4.18 Add Question (Multiple Choice) When the Multiple Choice tab is chosen from the Add Question page, Figure 4.18 is shown. Instructors should enter the question into the Text textbox. The potential answers should be entered into the Possible Answers textboxes next to the A, B, C, and D. Note that at least A and B must be populated. The correct Answer should be chosen by selecting one of the A, B, C, or D radio buttons. Additional information about the answer must be provided in the appropriate field. As before, the Save Question, Reset, Cancel, and Finish Quiz buttons are available at the bottom of the page. 41 Figure 4.19 Take Quiz (Multiple Choice Question) Figures 4.19, 4.20, and 4.21 show the view of the finished questions that the students will see. For a Multiple Choice type question the students must choose the correct answer from the letters displayed. They may then submit their answer and go on to the next question by selecting the Submit Answer button. If they wish to skip the current question and go on to the next question they may click the Skip Question button. Note that the top of the page displays the lesson name, number of the question, and the total number of questions in the quiz. 42 Figure 4.20 Take Quiz (Match Question) The screenshot in Figure 4.20 shows the students’ view of the Match Question. They will need to enter the letter of the correct answer in the textboxes shown under Letter of Answer. It is not case-sensitive so they may enter either lowercase or uppercase letters. They may then submit their answer and go on to the next question by selecting the Submit Answer button. If they wish to skip the current question and go on to the next question they may click the Skip Question button. Note that the top of the page displays the lesson name, number of the question, and the total number of questions in the quiz. 43 Figure 4.21 Take Quiz (True/False Question) The final type of quiz question is the True/False Question. The students will see the view from the screenshot in Figure 4.21. They must choose either the True radio button or the False radio button. The Skip Question and Submit Answer buttons are available at the bottom of the page. 44 Chapter 5 APPLICATION 5.1 Real-World Trial of Application On October 1, 2009, CAIT was utilized in a classroom setting by Professor Jones’ CSC 15 Programming Concepts and Methodology I class at the California State University, Sacramento. One of the concepts that Professor Jones was teaching her class involved logical operators. Through observing her creating a lesson about the topic and paying special attention to how she interacted with CAIT, then examining how eight students from her class used the application, notes were made on how to improve CAIT. Some of these ideas were subsequently added to CAIT, others were left for future work. 5.2 Instructor’s Perspective On September 25, 2009, Professor Jones created a lesson on logical operators. She completed a lesson page, a title page, and a quiz with three questions. Many things were learned by watching her work. After her experience was analyzed, changes were made to the program. It is believed that all instructors will appreciate the changes. One of the issues was that of readability. The font was difficult for her to read although it was the standard 8.25 pt Microsoft Sans Serif that is the default value for Microsoft Visual Studio. After consulting with a document about Computer as Instructional Aids [3], it was established that it is a good idea to use size 12 font. Subsequently, the font size on all of the pages was changed. Another issue that was discovered was that although it was possible to edit a lesson once it was started, CAIT 45 did not allow the user to change the name of the lesson. This was an oversight and the functionality was added. Overall, Professor Jones said that she thought that the project was a good idea and that she enjoyed using the program. She liked the reminders that the program would give her on the best practices to use for each page, but she thought it was a little tedious to have to answer questions about whether or not she used the best practices on every quiz page. She said that she would definitely use CAIT in her classroom and that it would be most useful for concepts that had a lot of little facts to remember. 5.3 Student’s Perspective During a lab session on October 1, 2009, eight students read the lesson and took the quiz that Professor Jones had prepared. After using CAIT, they completed a short questionnaire (see Figure 5.1). The results of the questionnaire can be found in Table 5.1. 46 Questionnaire on the Use of CAIT Please rate the following statements on a scale from 1 – 5. (1) meaning that you highly agree with the statement and (5) meaning you don’t agree wit the statement at all. 1. This application was easy to use. 1 2. 4. 5 2 3 4 5 2 3 4 5 The quiz portion of the program was easy to use. 1 2 3 4 5 Using the application was more fun than reading a textbook on the same subject. 1 6. 2 3 4 5 I could/would use this application from home. 1 7. 4 The title page helped me to understand what was expected of me. 1 5. 3 It was helpful that the lesson focused on only one concept. 1 3. 2 2 3 4 5 I think that this application could help me understand material from this class that I may not understand from the lectures or textbook. 1 2 3 4 5 Any additional comments: _______________________________________ ________Figure 5.1 Questionnaire on the Use of CAIT 47 Score Number (Percentage) 3 3 (37.5%) 1 (12.5%) 1 (12.5%) 2 (25.0%) 2 (25.0%) 3 (37.5%) 3 (37.5%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 1 (12.5%) 0 (0%) 0 (0%) 5 2 5 (62.5%) 7 (87.5%) 7 (87.5%) 6 (75.0%) 5 (62.5%) 5 (62.5%) 5 (62.5%) 4 1 Statement 1 Statement 2 Statement 3 Statement Number Statement 4 Statement 5 Statement 6 Statement 7 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) 0 (0%) Table 5.1 Results of Questionnaire The results show that overall the students thought that the application was easy to use and was a helpful tool. The lowest score was for the statement “Using this application was more fun than reading a textbook on the same subject”. The interpretation of this result is that students are not yet used to using Computer Assisted Tools in place of textbooks and lectures, and they may have felt that it was more cumbersome because of it. It is expected that if students were to become accustomed to using the program they would find more enjoyment in it. In the space that was available for additional comments a lot of positive feedback was received. One of the ideas that was provided by one of the students was that instructors should be able to add files that include video. This is a good idea and has been added it to the list of plans for future work. 48 Chapter 6 CONCLUSION AND FUTURE WORK 6.1 Conclusion The CAIT project demonstrates that it is possible to provide a lightweight, easyto-use teaching and learning device that can be of benefit to both students and instructors. Using CAIT, instructors are able to quickly and easily enter lessons and quizzes, and students are able to later read and study these lessons and take these quizzes. The value of distance-learning as a complement to traditional coursework has great value, and the CAIT tool provides an easy-to-use mechanism for allowing this distance-learning to take place. Teachers who do not have a lot of technical knowledge will find CAIT very user-friendly, and students will be able to use it effectively away from the classroom. CAIT’s principal value, of course, is that students will be able to easily review and learn the provided course material. 6.2 Future Work CAIT is now a Windows application, a good extension for CAIT would be to convert it into a Web application. This would lessen the required set-up and overhead for the instructors and students even more. Another enhancement that would be beneficial to CAIT would be the addition of video files to the list of files that CAIT accepts. Future work on CAIT should also consider implementing a centralized database of lessons and quizzes. This database should exist on some widely accessible server. Instructors could 49 supply new lessons to this central place, and students would access these lessons and quizzes from this facility. 50 APPENDIX Source Code in C# /********************************************************************* * Author: Suzanne Minton * File: AddEditLesson.cs * Date: 2008-2009 * Description: Page for adding and editing lessons *********************************************************************/ using using using using using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; System.Collections; System.Text.RegularExpressions; System.IO; System.Diagnostics; namespace MasterProject { public partial class AddEditLesson : Form { #region Variables private string mode; private string linkName; private string linkDescription; private int _lessonID; #endregion #region Constructors public AddEditLesson() { //User chose Add InitializeComponent(); this.Text = "New Lesson"; mode = "Add"; getLessonTitleandID(); this.txtTitle.ReadOnly = true; Program.addEditLessonOpen = true; } public AddEditLesson(string lessonTitle, int lessonID) { //User chose Edit _lessonID = lessonID; InitializeComponent(); this.Text = "Edit Lesson"; mode = "Edit"; this.txtText.Select(); editLesson(lessonTitle); populateGrid(); 51 Program.addEditLessonOpen = true; } #endregion #region Methods private void getLessonTitleandID() { dsCAITTableAdapters.LessonTableAdapter _taLesson = null; try { _taLesson = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); int maxLessonId = (int)_taLesson.MaxLessonId(); _lessonID = maxLessonId; string title = _taLesson.GetLessonTitleFromLessonId(maxLessonId).ToString(); this.txtTitle.Text = title; } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } private bool saveLesson() { bool saveSuccessful = false; if (txtText.TextLength >= 1) { FileManager fm = new FileManager(); if (fm.saveLesson(txtTitle.Text, txtText.Text)) { Program.isTempLesson = false; MessageBox.Show("Save Successful"); saveSuccessful = true; } else { MessageBox.Show("There was an error saving your lesson."); } } else //No input in text field { MessageBox.Show("Please enter text."); } return saveSuccessful; } private void editLesson(string lessonTitle) { this.txtTitle.Text = lessonTitle; FileManager fm = new FileManager(); txtText.Text = fm.viewLesson(lessonTitle); 52 } private bool saveLinkToDB(byte [] FileAttachment) { dsCAIT.AttachmentDataTable adt = null; bool linkFound = false; bool saveSuccessful = false; try { dsCAITTableAdapters.AttachmentTableAdapter _attachmentTA = new MasterProject.dsCAITTableAdapters.AttachmentTableAdapter(); adt = _attachmentTA.GetAttachmentsByLessonID(this._lessonID); } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } foreach (DataRow row in adt) { if (row.ItemArray.GetValue(1).ToString().Equals(linkName)) { linkFound = true; break; } } if (!linkFound) //Link doesn't exist in database yet { try { dsCAITTableAdapters.AttachmentTableAdapter _attachmentTA = new MasterProject.dsCAITTableAdapters.AttachmentTableAdapter(); int AttachmentID; _attachmentTA.InsertAttachment(linkName, linkDescription, FileAttachment, _lessonID); saveSuccessful = true; } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } if (!saveSuccessful) { MessageBox.Show("There was a problem saving the attachment."); } } else { MessageBox.Show("This attachment name has already been used for this lesson. \nPlease try again with another name."); } return saveSuccessful; } private void populateGrid() 53 { this.grdAttachments.DataSource = this.attachmentTableAdapter.GetAttachmentsByLessonID(_lessonID); } private void deleteTempLesson() { //Delete from lesson db and attachment db. dsCAITTableAdapters.LessonTableAdapter _taLesson = null; dsCAITTableAdapters.AttachmentTableAdapter _taAttachment = null; try { _taAttachment = new MasterProject.dsCAITTableAdapters.AttachmentTableAdapter(); _taAttachment.DeleteByLessonID(_lessonID); _taLesson = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); _taLesson.DeleteLesson(_lessonID); } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } #endregion #region Events private void btnAddEditLinkAttachment_Click(object sender, EventArgs e) { if (!Program.attachmentsOpen) { Attachment att = new Attachment(); if (att.ShowDialog() == DialogResult.OK) { linkName = att.LinkName; linkDescription = att.LinkDescription; saveLinkToDB(att.FileAttachment); populateGrid(); } } else { MessageBox.Show("You already have attachments opened."); } } private void btnSaveExit_Click(object sender, EventArgs e) { ensureBPUsed ebpu = new ensureBPUsed("Lesson"); DialogResult result = ebpu.ShowDialog(this); if (result == System.Windows.Forms.DialogResult.Yes) { if (saveLesson()) 54 { Program.isTempLesson = false; Program.okToCloseLesson = true; this.Close(); } } } private void btnCancel_Click(object sender, EventArgs e) { //Check to see if this is a tempLesson. if (Program.isTempLesson) { deleteTempLesson(); } Program.okToCloseLesson = true; this.Close(); } private void btnSave_Click(object sender, EventArgs e) { if (saveLesson()) { Program.okToCloseLesson = true; } } private void AddEditLesson_FormClosed(object sender, FormClosedEventArgs e) { Program.addEditLessonOpen = false; Program.okToCloseLesson = false; } private void txtText_LinkClicked(object sender, LinkClickedEventArgs e) { string[] Link = e.LinkText.Split('#'); string ID = Link[1]; } private void btnDeleteAttachment_Click(object sender, EventArgs e) { if (grdAttachments.SelectedRows.Count > 0) { DialogResult dr = MessageBox.Show("Are you sure you want to delete this attachment?", "Delete Attachment", MessageBoxButtons.YesNo); if (dr == System.Windows.Forms.DialogResult.Yes) { DataGridViewRow selectedRow = grdAttachments.SelectedRows[0]; int attachId = (int)selectedRow.Cells[0].Value; try { dsCAITTableAdapters.AttachmentTableAdapter ata = new MasterProject.dsCAITTableAdapters.AttachmentTableAdapter(); int result = ata.DeleteAttachment(attachId); populateGrid(); 55 } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } } } private void btnViewAttachment_Click(object sender, EventArgs e) { if (grdAttachments.SelectedRows.Count > 0) { DataGridViewRow selectedRow = grdAttachments.SelectedRows[0]; int attachId = (int)selectedRow.Cells[0].Value; try { dsCAITTableAdapters.AttachmentTableAdapter ata = new MasterProject.dsCAITTableAdapters.AttachmentTableAdapter(); DataTable dtAttachment = ata.GetAttachmentByAttachmentID(attachId); if (dtAttachment.Rows.Count == 1) { byte[] data = (byte[])dtAttachment.Rows[0]["Attachment"]; File.WriteAllBytes(@"C:\temp\lessons\" + dtAttachment.Rows[0]["linkname"], data); Process.Start(@"C:\temp\lessons\" + dtAttachment.Rows[0]["linkname"]); } } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } } private void AddEditLesson_FormClosing(object sender, FormClosingEventArgs e) { if (!Program.okToCloseLesson) { MessageBox.Show("Please exit this page with either the Save and Exit button or the Cancel button."); e.Cancel = true; } } #endregion } } 56 /********************************************************************* * Author: Suzanne Minton * File: AddEditQuiz.cs * Date: 2008-2009 * Description: Page for adding and editing quizzes * *******************************************************************/ using using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; System.Collections; namespace MasterProject { public partial class AddEditQuiz : Form { #region Declarations string localTitle; #endregion #region Constructor public AddEditQuiz() { InitializeComponent(); this.quizTableAdapter.Fill(this.dsCAIT.Quiz); localTitle = ""; Program.addEditQuizOpen = true; } public AddEditQuiz(string quizTitle) { localTitle = quizTitle; InitializeComponent(); Program.addEditQuizOpen = true; } #endregion #region Initializers private void AddEditQuiz_Load(object sender, EventArgs e) { try { if (localTitle != null && !"".Equals(localTitle)) { //this.quizTableAdapter.FillQuizQuestionList(this.dsCAIT.Quiz); this.cbxLessonName.DataSource = this.lessonTableAdapter.ReturnLessonDatatable(); this.cbxLessonName.SelectedValue = localTitle; makePretty(); } } catch (Exception ex) { MessageBox.Show("There was a loading the lessons."); } 57 } #endregion #region Methods private void fillQuestionList(string lessonTitle) { dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); try { int id = Convert.ToInt32(lta.GetLessonIdFromTitle(lessonTitle)); this.grdQuestions.DataSource = this.quizTableAdapter.GetDataByLessonId(id); } catch (Exception ex) { MessageBox.Show("There was a problem getting the quiz data."); } makePretty(); } private void makePretty() { for (int rowNum = 0; rowNum < grdQuestions.Rows.Count; rowNum++) { if (grdQuestions.Rows[rowNum].Cells["typeOfQuestionDataGridViewTextBoxColumn"].Val ue.ToString().Equals("Match")) { string savedText = grdQuestions.Rows[rowNum].Cells["questionTextDataGridViewTextBoxColumn"].Value. ToString(); int place = savedText.IndexOf(";;;"); if (place > 0) { string val1 = savedText.Substring(0, place); string val2 = savedText.Substring(place + 3); string newText = "Please match the " + val1 + " to the " + val2; grdQuestions.Rows[rowNum].Cells["questionTextDataGridViewTextBoxColumn"].Value = newText; } } } } private void callDBToChangeQuestionNumber(int questionNum, int quizID) { try { dsCAITTableAdapters.QuizTableAdapter qta = new MasterProject.dsCAITTableAdapters.QuizTableAdapter(); int result = qta.UpdateQuestionNumber(questionNum, quizID); } catch (Exception ex) { 58 MessageBox.Show("There was a problem with the database."); } } private void determineIfQuizComplete(string lessonTitle) { try { dsCAITTableAdapters.QuizTableAdapter qta = new MasterProject.dsCAITTableAdapters.QuizTableAdapter(); dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); int id = Convert.ToInt32(lta.GetLessonIdFromTitle(lessonTitle)); dsCAIT.QuizDataTable qdt = qta.getQuestionTypesFromLessonId(id); string type = ""; ArrayList al = new ArrayList(); string status = ""; for (int i = 0; i < qdt.Rows.Count; i++) { type = qdt.Rows[i].ItemArray[4].ToString(); if (!al.Contains(type)) { al.Add(type); } } if (al.Count > 2) { status = "Complete"; } else { status = "Incomplete"; } lta.UpdateQuizStatus(status, id); } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } #endregion #region Events private void cbxLessonName_SelectedIndexChanged(object sender, EventArgs e) { string title = cbxLessonName.SelectedValue.ToString(); fillQuestionList(title); } private void btnAddQuestion_Click(object sender, EventArgs e) { 59 if (!Program.addQuestionOpen) { AddQuestion aq = new AddQuestion(cbxLessonName.SelectedValue.ToString()); aq.Show(); } else { MessageBox.Show("You already have a question opened."); } } private void btnExit_Click(object sender, EventArgs e) { this.Close(); } private void lnkAddEditQuizRefresh_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { string title = cbxLessonName.SelectedValue.ToString(); fillQuestionList(title); } private void btnEditQuestion_Click(object sender, EventArgs e) { if (!Program.addQuestionOpen) { if (grdQuestions.SelectedRows.Count > 0) { DataGridViewRow selectedRow = grdQuestions.SelectedRows[0]; int quizId = (int)selectedRow.Cells["quizIdDataGridViewTextBoxColumn"].Value; AddQuestion aq = new AddQuestion(cbxLessonName.SelectedValue.ToString(), quizId); aq.Show(); } else { MessageBox.Show("Please select a question to edit."); } } else { MessageBox.Show("You already have a question opened."); } } private void btnDeleteQuestion_Click(object sender, EventArgs e) { if (grdQuestions.SelectedRows.Count > 0) { DialogResult dr = MessageBox.Show("Are you sure you want to delete this quiz question?", "Delete Quiz Question", MessageBoxButtons.YesNo); if (dr == System.Windows.Forms.DialogResult.Yes) { DataGridViewRow selectedRow = grdQuestions.SelectedRows[0]; int quizId = (int)selectedRow.Cells["quizIdDataGridViewTextBoxColumn"].Value; 60 int questNum = (int)selectedRow.Cells["questionNumberDataGridViewTextBoxColumn"].Value; try { dsCAITTableAdapters.QuizTableAdapter qta = new MasterProject.dsCAITTableAdapters.QuizTableAdapter(); int result = qta.DeleteQuizQuestion(quizId); for (int i = 0; i < grdQuestions.Rows.Count; i++) { int tempQuestNum = (int)grdQuestions.Rows[i].Cells["questionNumberDataGridViewTextBoxColumn"].Valu e; if (tempQuestNum > questNum) { dsCAITTableAdapters.QuizTableAdapter tempQta = new MasterProject.dsCAITTableAdapters.QuizTableAdapter(); int tmpTempQuestNum = tempQuestNum - 1; tempQta.UpdateQuestionNumber(tmpTempQuestNum, (int)grdQuestions.Rows[i].Cells["quizIdDataGridViewTextBoxColumn"].Value); } } string title = cbxLessonName.SelectedValue.ToString(); determineIfQuizComplete(title); fillQuestionList(title); } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } } } private void AddEditQuiz_FormClosed(object sender, FormClosedEventArgs e) { Program.addEditQuizOpen = false; } private void lnkMoveUp_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { if (grdQuestions.SelectedRows.Count > 0) { DataGridViewRow selectedRow = grdQuestions.SelectedRows[0]; int origQuestNum = (int)selectedRow.Cells["questionNumberDataGridViewTextBoxColumn"].Value; try { if (origQuestNum > 1) { int origQuizID = (int)selectedRow.Cells["quizIdDataGridViewTextBoxColumn"].Value; origQuestNum--; 61 int changedQuestionNumber = (int)grdQuestions.Rows[origQuestNum 1].Cells["questionNumberDataGridViewTextBoxColumn"].Value; changedQuestionNumber++; int changedQuizID = (int)grdQuestions.Rows[origQuestNum - 1].Cells["quizIdDataGridViewTextBoxColumn"].Value; callDBToChangeQuestionNumber(changedQuestionNumber, changedQuizID); callDBToChangeQuestionNumber(origQuestNum, origQuizID); string title = cbxLessonName.SelectedValue.ToString(); fillQuestionList(title); this.grdQuestions.Rows[origQuestNum - 1].Selected = true; this.grdQuestions.CurrentCell = this.grdQuestions.Rows[origQuestNum - 1].Cells[2]; } else { MessageBox.Show("Question can not be moved up."); } } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } } private void lnkMoveDown_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { if (grdQuestions.SelectedRows.Count > 0) { DataGridViewRow selectedRow = grdQuestions.SelectedRows[0]; int origQuestNum = (int)selectedRow.Cells["questionNumberDataGridViewTextBoxColumn"].Value; try { if (origQuestNum < grdQuestions.Rows.Count) { int origQuizID = (int)selectedRow.Cells["quizIdDataGridViewTextBoxColumn"].Value; origQuestNum++; int changedQuestionNumber = (int)grdQuestions.Rows[origQuestNum 1].Cells["questionNumberDataGridViewTextBoxColumn"].Value; changedQuestionNumber--; int changedQuizID = (int)grdQuestions.Rows[origQuestNum - 1].Cells["quizIdDataGridViewTextBoxColumn"].Value; callDBToChangeQuestionNumber(changedQuestionNumber, changedQuizID); callDBToChangeQuestionNumber(origQuestNum, origQuizID); 62 string title = cbxLessonName.SelectedValue.ToString(); fillQuestionList(title); this.grdQuestions.Rows[origQuestNum - 1].Selected = true; this.grdQuestions.CurrentCell = this.grdQuestions.Rows[origQuestNum - 1].Cells[2]; } else { MessageBox.Show("Question can not be moved down."); } } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } } } #endregion } /********************************************************************* * Author: Suzanne Minton * File: AddQuestion.cs * Date: 2008-2009 * Description: Page for adding and editing quiz questions * *******************************************************************/ using using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; System.Collections; namespace MasterProject { public partial class AddQuestion : Form { #region Variables private string localTitle; private int quizQuestionID; private string mode = ""; bool continueFromEnsureBPUsed = false; #endregion #region Constructors public AddQuestion() 63 { InitializeComponent(); mode = "Add"; Program.addQuestionOpen = true; } public AddQuestion(string lessonTitle) { InitializeComponent(); localTitle = lessonTitle; mode = "Add"; initialSetUpForNewQuestion(); Program.addQuestionOpen = true; } public AddQuestion(string lessonTitle, int quizQuestID) { InitializeComponent(); localTitle = lessonTitle; quizQuestionID = quizQuestID; mode = "Edit"; dsCAIT.QuizDataTable qdt = retrieveQuestion(); setUpQuestForEdit(qdt); Program.addQuestionOpen = true; } #endregion #region Methods private void initialSetUpForNewQuestion() { lblLessonName.Text = localTitle; int lastQuestionNum = 1; try { dsCAITTableAdapters.QuizTableAdapter qta = new MasterProject.dsCAITTableAdapters.QuizTableAdapter(); dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); int id = Convert.ToInt32(lta.GetLessonIdFromTitle(localTitle)); object tempObj = qta.maxQuestionNumber(id); if (tempObj != null) { lastQuestionNum = (int)tempObj + 1; } this.lblQuestionNum.Text = lastQuestionNum.ToString(); } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } private dsCAIT.QuizDataTable retrieveQuestion() 64 { dsCAITTableAdapters.QuizTableAdapter qta = new MasterProject.dsCAITTableAdapters.QuizTableAdapter(); dsCAIT.QuizDataTable qdt = new dsCAIT.QuizDataTable(); try { qta.retrieveQuizQuestion(qdt, quizQuestionID); } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } return qdt; } private void setUpQuestForEdit(dsCAIT.QuizDataTable qdt) { string questType = qdt.Rows[0].ItemArray[4].ToString(); btnFinish.Hide(); btnReset.Hide(); btnCancel.Location = new System.Drawing.Point(697, 432); btnSave.Location = new System.Drawing.Point(593, 432); this.Text = "Edit Question"; try { dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); string title = lta.GetLessonTitleFromLessonId((int)qdt.Rows[0].ItemArray[12]); this.lblLessonName.Text = title; } catch (Exception ex) { MessageBox.Show("Could not retrieve Lesson Title"); } this.lblQuestionNum.Text = qdt.Rows[0].ItemArray[1].ToString(); if (questType.Equals("MC")) { //if (tbctrlQuestions.TabPages.Contains(tbctrlQuestions.TabPages["True/False"])) if(tbctrlQuestions.TabPages.Contains(tbTF)) { tbctrlQuestions.TabPages.Remove(tbTF); } //if (tbctrlQuestions.TabPages.Contains(tbctrlQuestions.TabPages["Match"])) if(tbctrlQuestions.TabPages.Contains(tbMatch)) { tbctrlQuestions.TabPages.Remove(tbMatch); } populateMCFields(qdt); } else if (questType.Equals("T/F")) 65 { if (tbctrlQuestions.TabPages.Contains(tbMatch)) { tbctrlQuestions.TabPages.Remove(tbMatch); } if (tbctrlQuestions.TabPages.Contains(tbMC)) { tbctrlQuestions.TabPages.Remove(tbMC); } populateTFFields(qdt); } else { if (tbctrlQuestions.TabPages.Contains(tbTF)) { tbctrlQuestions.TabPages.Remove(tbTF); } if (tbctrlQuestions.TabPages.Contains(tbMC)) { tbctrlQuestions.TabPages.Remove(tbMC); } populateMatchFields(qdt); } } private bool validateMatchQuestion() { bool validLetter = true; ArrayList col1; ArrayList col2; //Put all of Column 1 in col1 array col1 = constructCol1Array(); //Put all of Column 2 in col2 array col2 = constructCol2Array(); //Are there the same amouont of items in col1 and col2? if (col1.Count == col2.Count) { ArrayList loa = constructLOAArray(); if (col1.Count == loa.Count) { ArrayList validAnswers = new ArrayList(); string[] possibleAnswers = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J" }; for(int i = 0; i < loa.Count; i++) { validAnswers.Add(possibleAnswers[i].ToString()); } // We now have the loa arraylist that the user entered and the validanswers arraylist that are valid answers. Make sure that they are the same. ArrayList al1 = (ArrayList)loa.Clone(); ArrayList al2 = (ArrayList)validAnswers.Clone(); 66 for (int i = 0; i < al1.Count; i++) { for (int j = 0; j < al2.Count; j++) { if (al1[i].ToString().ToUpper().Equals(al2[j].ToString().ToUpper())) { al1.RemoveAt(i); al2.RemoveAt(j); i--; break; } } } //After going through the arrays if there are any letters left in the arrays we know there was a problem with the letters the user entered if (al1.Count > 0) { MessageBox.Show("The letters entered into the Letter of Answer column do not match the \nactual letters of the textboxes you entered in Column 2. \n\nPlease look over your entries and try again."); validLetter = false; } } else { MessageBox.Show("There are not the same amount of items in Column 1 and Column 2 \nas there are in the Letter of Answer column. \n\nColumn 1 and Column 2 have " + col1.Count + " items. \nThe Letter of Answer column has " + loa.Count + " items."); validLetter = false; } } else { MessageBox.Show("There are not the same amount of items in Column 1 as there are in Column 2. \n\nColumn 1 has " + col1.Count + " items. \nColumn 2 has " + col2.Count + " items."); validLetter = false; } return validLetter; } private ArrayList constructCol1Array() { ArrayList col1 = new ArrayList(); if (txtMatch1_1.Text != null && col1.Add(txtMatch1_1.Text); if (txtMatch1_2.Text != null && col1.Add(txtMatch1_2.Text); if (txtMatch1_3.Text != null && col1.Add(txtMatch1_3.Text); if (txtMatch1_4.Text != null && col1.Add(txtMatch1_4.Text); if (txtMatch1_5.Text != null && col1.Add(txtMatch1_5.Text); !"".Equals(txtMatch1_1.Text)) !"".Equals(txtMatch1_2.Text)) !"".Equals(txtMatch1_3.Text)) !"".Equals(txtMatch1_4.Text)) !"".Equals(txtMatch1_5.Text)) 67 if (txtMatch1_6.Text != null && !"".Equals(txtMatch1_6.Text)) col1.Add(txtMatch1_6.Text); if (txtMatch1_7.Text != null && !"".Equals(txtMatch1_7.Text)) col1.Add(txtMatch1_7.Text); if (txtMatch1_8.Text != null && !"".Equals(txtMatch1_8.Text)) col1.Add(txtMatch1_8.Text); if (txtMatch1_9.Text != null && !"".Equals(txtMatch1_9.Text)) col1.Add(txtMatch1_9.Text); if (txtMatch1_10.Text != null && !"".Equals(txtMatch1_10.Text)) col1.Add(txtMatch1_10.Text); return col1; } private ArrayList constructCol2Array() { ArrayList col2 = new ArrayList(); if (txtMatch3_1.Text != null && !"".Equals(txtMatch3_1.Text)) col2.Add(txtMatch3_1.Text); if (txtMatch3_2.Text != null && !"".Equals(txtMatch3_2.Text)) col2.Add(txtMatch3_2.Text); if (txtMatch3_3.Text != null && !"".Equals(txtMatch3_3.Text)) col2.Add(txtMatch3_3.Text); if (txtMatch3_4.Text != null && !"".Equals(txtMatch3_4.Text)) col2.Add(txtMatch3_4.Text); if (txtMatch3_5.Text != null && !"".Equals(txtMatch3_5.Text)) col2.Add(txtMatch3_5.Text); if (txtMatch3_6.Text != null && !"".Equals(txtMatch3_6.Text)) col2.Add(txtMatch3_6.Text); if (txtMatch3_7.Text != null && !"".Equals(txtMatch3_7.Text)) col2.Add(txtMatch3_7.Text); if (txtMatch3_8.Text != null && !"".Equals(txtMatch3_8.Text)) col2.Add(txtMatch3_8.Text); if (txtMatch3_9.Text != null && !"".Equals(txtMatch3_9.Text)) col2.Add(txtMatch3_9.Text); if (txtMatch3_10.Text != null && !"".Equals(txtMatch3_10.Text)) col2.Add(txtMatch3_10.Text); return col2; } private ArrayList constructLOAArray() { ArrayList loa = new ArrayList(); //Same amount of items in Column 1 and Column 2, put LOA column in array if (txtMatch2_1.Text != null && loa.Add(txtMatch2_1.Text); if (txtMatch2_2.Text != null && loa.Add(txtMatch2_2.Text); if (txtMatch2_3.Text != null && loa.Add(txtMatch2_3.Text); if (txtMatch2_4.Text != null && loa.Add(txtMatch2_4.Text); if (txtMatch2_5.Text != null && loa.Add(txtMatch2_5.Text); if (txtMatch2_6.Text != null && loa.Add(txtMatch2_6.Text); if (txtMatch2_7.Text != null && !"".Equals(txtMatch2_1.Text)) !"".Equals(txtMatch2_2.Text)) !"".Equals(txtMatch2_3.Text)) !"".Equals(txtMatch2_4.Text)) !"".Equals(txtMatch2_5.Text)) !"".Equals(txtMatch2_6.Text)) !"".Equals(txtMatch2_7.Text)) 68 loa.Add(txtMatch2_7.Text); if (txtMatch2_8.Text != null && !"".Equals(txtMatch2_8.Text)) loa.Add(txtMatch2_8.Text); if (txtMatch2_9.Text != null && !"".Equals(txtMatch2_9.Text)) loa.Add(txtMatch2_9.Text); if (txtMatch2_10.Text != null && !"".Equals(txtMatch2_10.Text)) loa.Add(txtMatch2_10.Text); return loa; } private bool saveQuestion(string questionType) { bool saved = false; string lessonName = lblLessonName.Text; string questionNum = lblQuestionNum.Text; int qNum = 0; int id = 0; dsCAITTableAdapters.QuizTableAdapter qta = new MasterProject.dsCAITTableAdapters.QuizTableAdapter(); dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); try { qNum = Int32.Parse(questionNum); id = Convert.ToInt32(lta.GetLessonIdFromTitle(lessonName)); } catch (Exception ex) { MessageBox.Show("There was a problem parsing the question number."); } string answer = ""; if (qNum != 0 && id != 0) { if (questionType.Equals("T/F")) { if (rbTrue.Checked) { answer = "True"; } else { answer = "False"; } try { if (mode.Equals("Add")) { qta.SaveTFQuestion(id, qNum, txtTFText.Text, answer, "T/F", txtTFAddInfo.Text); } else { 69 qta.UpdateTFQuestion(txtTFText.Text, answer, txtTFAddInfo.Text, quizQuestionID); } saved = true; } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } else if (questionType.Equals("MC")) { if (rbA.Checked) { answer = "A"; } else if (rbB.Checked) { answer = "B"; } else if (rbC.Checked) { answer = "C"; } else { answer = "D"; } try { if (mode.Equals("Add")) { qta.SaveMCQuestion(id, qNum, txtMCText.Text, answer, "MC", txtMCAddInfo.Text, txtA.Text, txtB.Text, txtC.Text, txtD.Text); } else { qta.UpdateMCQuestion(txtMCText.Text, answer, txtMCAddInfo.Text, txtA.Text, txtB.Text, txtC.Text, txtD.Text, quizQuestionID); } saved = true; } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } else if (questionType.Equals("Match")) { //Save match question string matchText = txtCol1.Text + ";;;" + txtCol2.Text; string answerMatch = constructAnswerText(); string col1Match = constructCol1Text(); string col2Match = constructCol2Text(); try { if (mode.Equals("Add")) 70 { qta.SaveMatchQuestion(id, qNum, matchText, answerMatch, "Match", col1Match, col2Match); } else { qta.UpdateMatchQuestion(matchText, answerMatch, col1Match, col2Match, quizQuestionID); } saved = true; } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } } return saved; } private string constructAnswerText() { string answerText = ""; ArrayList tempLOA = constructLOAArray(); for (int i = 0; i < tempLOA.Count; i++) { answerText += tempLOA[i].ToString() + ";;;"; } return answerText; } private string constructCol1Text() { string col1Text = ""; ArrayList tempCol1 = constructCol1Array(); for (int i = 0; i < tempCol1.Count; i++) { col1Text += tempCol1[i].ToString() + ";;;"; } return col1Text; } private string constructCol2Text() { string col2Text = ""; ArrayList tempCol2 = constructCol2Array(); for (int i = 0; i < tempCol2.Count; i++) { col2Text += tempCol2[i].ToString() + ";;;"; } return col2Text; } 71 private void populateMCFields(dsCAIT.QuizDataTable qdt) { //Populate Question Text this.txtMCText.Text = qdt.Rows[0].ItemArray[2].ToString(); //Populate Possible Answer A this.txtA.Text = qdt.Rows[0].ItemArray[8].ToString(); //Populate Possible Answer B this.txtB.Text = qdt.Rows[0].ItemArray[9].ToString(); //Populate Possible Answer C this.txtC.Text = qdt.Rows[0].ItemArray[10].ToString(); //Populate Possible Answer D this.txtD.Text = qdt.Rows[0].ItemArray[11].ToString(); //Check either A, B, C, or D for the correct answer switch (qdt.Rows[0].ItemArray[3].ToString()) { case "A": rbA.Checked = true; break; case "B": rbB.Checked = true; break; case "C": rbC.Checked = true; break; case "D": rbD.Checked = true; break; default: rbA.Checked = true; break; } //Populate Additional Information txtMCAddInfo.Text = qdt.Rows[0].ItemArray[5].ToString(); } private void populateMatchFields(dsCAIT.QuizDataTable qdt) { //Populate text for column 1 and column 2 string tmpText = qdt.Rows[0].ItemArray[2].ToString(); int place = tmpText.IndexOf(";;;"); txtCol1.Text = tmpText.Substring(0, place); txtCol2.Text = tmpText.Substring(place + 3); //Populate Column 1 string tmpCol1 = qdt.Rows[0].ItemArray[6].ToString(); //Create Array that contains all values ArrayList alCol1 = new ArrayList(); int i = 0; while (i < tmpCol1.Length) { int tmpPlace = tmpCol1.IndexOf(";;;", i); alCol1.Add(tmpCol1.Substring(i, tmpPlace - i)); 72 i = tmpPlace + 3; } //Set txt boxes to array values if(alCol1.Count > 0) txtMatch1_1.Text = alCol1[0].ToString(); if (alCol1.Count > 1) txtMatch1_2.Text = alCol1[1].ToString(); if (alCol1.Count > 2) txtMatch1_3.Text = alCol1[2].ToString(); if (alCol1.Count > 3) txtMatch1_4.Text = alCol1[3].ToString(); if (alCol1.Count > 4) txtMatch1_5.Text = alCol1[4].ToString(); if (alCol1.Count > 5) txtMatch1_6.Text = alCol1[5].ToString(); if (alCol1.Count > 6) txtMatch1_7.Text = alCol1[6].ToString(); if (alCol1.Count > 7) txtMatch1_8.Text = alCol1[7].ToString(); if (alCol1.Count > 8) txtMatch1_9.Text = alCol1[8].ToString(); if (alCol1.Count > 9) txtMatch1_10.Text = alCol1[9].ToString(); //Populate Column 2 string tmpCol2 = qdt.Rows[0].ItemArray[7].ToString(); //Create Array that contains all values ArrayList alCol2 = new ArrayList(); int i2 = 0; while (i2 < tmpCol2.Length) { int tmpPlace = tmpCol2.IndexOf(";;;", i2); alCol2.Add(tmpCol2.Substring(i2, tmpPlace - i2)); i2 = tmpPlace + 3; } //Set txt boxes to array values if (alCol2.Count > 0) txtMatch3_1.Text = alCol2[0].ToString(); if (alCol2.Count > 1) txtMatch3_2.Text = alCol2[1].ToString(); if (alCol2.Count > 2) txtMatch3_3.Text = alCol2[2].ToString(); if (alCol2.Count > 3) txtMatch3_4.Text = alCol2[3].ToString(); if (alCol2.Count > 4) txtMatch3_5.Text = alCol2[4].ToString(); if (alCol2.Count > 5) txtMatch3_6.Text = alCol2[5].ToString(); if (alCol2.Count > 6) txtMatch3_7.Text = alCol2[6].ToString(); if (alCol2.Count > 7) txtMatch3_8.Text = alCol2[7].ToString(); if (alCol2.Count > 8) txtMatch3_9.Text = alCol2[8].ToString(); if (alCol2.Count > 9) txtMatch3_10.Text = alCol2[9].ToString(); 73 //Populate LOA string tmpCol3 = qdt.Rows[0].ItemArray[3].ToString(); //Create Array that contains all values ArrayList alCol3 = new ArrayList(); int i3 = 0; while (i3 < tmpCol3.Length) { int tmpPlace = tmpCol3.IndexOf(";;;", i3); alCol3.Add(tmpCol3.Substring(i3, tmpPlace - i3)); i3 = tmpPlace + 3; } //Set txt boxes to array values if (alCol3.Count > 0) txtMatch2_1.Text = alCol3[0].ToString(); if (alCol3.Count > 1) txtMatch2_2.Text = alCol3[1].ToString(); if (alCol3.Count > 2) txtMatch2_3.Text = alCol3[2].ToString(); if (alCol3.Count > 3) txtMatch2_4.Text = alCol3[3].ToString(); if (alCol3.Count > 4) txtMatch2_5.Text = alCol3[4].ToString(); if (alCol3.Count > 5) txtMatch2_6.Text = alCol3[5].ToString(); if (alCol3.Count > 6) txtMatch2_7.Text = alCol3[6].ToString(); if (alCol3.Count > 7) txtMatch2_8.Text = alCol3[7].ToString(); if (alCol3.Count > 8) txtMatch2_9.Text = alCol3[8].ToString(); if (alCol3.Count > 9) txtMatch2_10.Text = alCol3[9].ToString(); } private void populateTFFields(dsCAIT.QuizDataTable qdt) { //Populate Question Text this.txtTFText.Text = qdt.Rows[0].ItemArray[2].ToString(); //Check either True or False if (qdt.Rows[0].ItemArray[3].ToString().Equals("True")) { rbTrue.Checked = true; } else { rbFalse.Checked = true; } //Populate Answer Description txtTFAddInfo.Text = qdt.Rows[0].ItemArray[5].ToString(); } private void ontoNewQuestion(bool previousQuestionSaved) 74 { if (previousQuestionSaved) { initialSetUpForNewQuestion(); } //Clear T/F txtTFText.Text = ""; rbTrue.Checked = false; rbFalse.Checked = false; txtTFAddInfo.Text = ""; //Clear Match txtCol1.Text = ""; txtCol2.Text = ""; txtMatch1_1.Text = ""; txtMatch1_2.Text = ""; txtMatch1_3.Text = ""; txtMatch1_4.Text = ""; txtMatch1_5.Text = ""; txtMatch1_6.Text = ""; txtMatch1_7.Text = ""; txtMatch1_8.Text = ""; txtMatch1_9.Text = ""; txtMatch1_10.Text = ""; txtMatch2_1.Text = ""; txtMatch2_2.Text = ""; txtMatch2_3.Text = ""; txtMatch2_4.Text = ""; txtMatch2_5.Text = ""; txtMatch2_6.Text = ""; txtMatch2_7.Text = ""; txtMatch2_8.Text = ""; txtMatch2_9.Text = ""; txtMatch2_10.Text = ""; txtMatch3_1.Text = ""; txtMatch3_2.Text = ""; txtMatch3_3.Text = ""; txtMatch3_4.Text = ""; txtMatch3_5.Text = ""; txtMatch3_6.Text = ""; txtMatch3_7.Text = ""; txtMatch3_8.Text = ""; txtMatch3_9.Text = ""; txtMatch3_10.Text = ""; //Clear MC txtMCText.Text = ""; txtA.Text = ""; txtB.Text = ""; txtC.Text = ""; txtD.Text = ""; rbA.Checked = false; rbB.Checked = false; rbC.Checked = false; rbD.Checked = false; txtMCAddInfo.Text = ""; } private bool shouldSave() 75 { bool valid = false; if (tbctrlQuestions.SelectedTab == tbMC) { // tab MC if (!txtMCText.Text.Equals("") || !txtA.Text.Equals("") || !txtB.Text.Equals("") || !txtC.Text.Equals("") || !txtD.Text.Equals("") || rbA.Checked == true || rbB.Checked == true || rbC.Checked == true || rbD.Checked == true || !txtMCAddInfo.Text.Equals("")) { DialogResult result1 = MessageBox.Show("Would you like to save this question?", "Wish To Save", MessageBoxButtons.YesNo); if (result1 == DialogResult.Yes) { valid = saveMCQuestion(); } else { //Don't save so valid is true valid = true; ontoNewQuestion(false); } } else { //Empty so valid is true valid = true; } } else if (tbctrlQuestions.SelectedTab == tbTF) { //tab T/F if (!txtTFText.Text.Equals("") || rbTrue.Checked == true || rbFalse.Checked == true || !txtTFAddInfo.Text.Equals("")) { DialogResult result1 = MessageBox.Show("Would you like to save this question?", "Wish To Save", MessageBoxButtons.YesNo); if (result1 == DialogResult.Yes) { valid = saveTFQuestion(); } else { //Don't save so valid is true valid = true; ontoNewQuestion(false); } } else { //Empty so valid is true 76 valid = true; } } else { //tab Match if ((!txtCol1.Text.Equals("") && !txtCol1.Text.Equals("<Enter type of data in first column>")) || (!txtCol2.Text.Equals("") && !txtCol2.Text.Equals("<Enter type of data in second column>")) || !txtMatch1_1.Text.Equals("") || !txtMatch1_2.Text.Equals("") || !txtMatch1_3.Text.Equals("") || !txtMatch1_4.Text.Equals("") || !txtMatch1_5.Text.Equals("") || !txtMatch1_6.Text.Equals("") || !txtMatch1_7.Text.Equals("") || !txtMatch1_8.Text.Equals("") || !txtMatch1_9.Text.Equals("") || !txtMatch1_10.Text.Equals("") || !txtMatch2_1.Text.Equals("") || !txtMatch2_2.Text.Equals("") || !txtMatch2_3.Text.Equals("") || !txtMatch2_4.Text.Equals("") || !txtMatch2_5.Text.Equals("") || !txtMatch2_6.Text.Equals("") || !txtMatch2_7.Text.Equals("") || !txtMatch2_8.Text.Equals("") || !txtMatch2_9.Text.Equals("") || !txtMatch2_10.Text.Equals("") || !txtMatch3_1.Text.Equals("") || !txtMatch3_2.Text.Equals("") || !txtMatch3_3.Text.Equals("") || !txtMatch3_4.Text.Equals("") || !txtMatch3_5.Text.Equals("") || !txtMatch3_6.Text.Equals("") || !txtMatch3_7.Text.Equals("") || !txtMatch3_8.Text.Equals("") || !txtMatch3_9.Text.Equals("") || !txtMatch3_10.Text.Equals("")) { DialogResult result1 = MessageBox.Show("Would you like to save this question?", "Wish To Save", MessageBoxButtons.YesNo); if (result1 == DialogResult.Yes) { valid = saveMatchQuestion(); } else { //Don't save so valid is true valid = true; ontoNewQuestion(false); } } else { //Empty so valid is true valid = true; } } 77 return valid; } private bool saveMCQuestion() { bool saved = false; if (txtMCText.Text.Length > 0) { if (txtA.Text.Length > 0 && txtB.Text.Length > 0) { if (rbA.Checked || rbB.Checked || rbC.Checked || rbD.Checked) { if ((rbC.Checked == false) || (rbC.Checked == true && txtC.Text.Length > 0)) { if ((rbD.Checked == false) || (rbD.Checked == true && txtD.Text.Length > 0)) { if ((txtD.Text.Length <= 0) || (txtC.Text.Length > 0)) { if (txtMCAddInfo.Text.Length > 0) { ensureBPUsed ebpu = new ensureBPUsed("MC"); DialogResult result = ebpu.ShowDialog(this); if (result == System.Windows.Forms.DialogResult.Yes) { if (saveQuestion("MC")) { MessageBox.Show("Question has been saved."); ontoNewQuestion(true); saved = true; } else { MessageBox.Show("There is a problem and the question has not been saved."); } } } else { MessageBox.Show("You must input additional information about the answer.", "Error"); } } else { MessageBox.Show("If there is a possible answer in text box D, then there needs to be a possible answer in text box C.", "Error"); } } else 78 { MessageBox.Show("If radio button D is chosen as the correct answer, then there needs to be a possible answer in text box D.", "Error"); } } else { MessageBox.Show("If radio button C is chosen as the correct answer, then there needs to be a possible answer in text box C.", "Error"); } } else { MessageBox.Show("At least one of the radio buttons must be checked to denote the correct answer.", "Error"); } } else { MessageBox.Show("There must be at least two choices for answers.\nOne in text box A and one in text box B.", "Error"); } } else { MessageBox.Show("You must enter a statement in the main text box.", "Error"); } return saved; } private bool saveTFQuestion() { bool saved = false; if (txtTFText.Text.Length > 0) { if (rbTrue.Checked || rbFalse.Checked) { if (txtTFAddInfo.Text.Length > 0) { ensureBPUsed ebpu = new ensureBPUsed("TF"); DialogResult result = ebpu.ShowDialog(this); if (result == System.Windows.Forms.DialogResult.Yes) { if (saveQuestion("T/F")) { MessageBox.Show("Question has been saved."); ontoNewQuestion(true); saved = true; } else { MessageBox.Show("There is a problem and the question has not been saved."); } } } else 79 { MessageBox.Show("You must input additional information about the answer.", "Error"); } } else { MessageBox.Show("At least one of the radio buttons must be checked to denote the correct answer.", "Error"); } } else { MessageBox.Show("You must enter a question in the main text box.", "Error"); } return saved; } private bool saveMatchQuestion() { bool saved = false; if (txtCol1.Text.Length > 0 && !txtCol1.Text.Equals("<Enter type of data in first column>")) { if (txtCol2.Text.Length > 0 && !txtCol2.Text.Equals("<Enter type of data in second column>")) { if (txtMatch1_1.Text.Length > 0 && txtMatch2_1.Text.Length > 0 && txtMatch3_1.Text.Length > 0 && txtMatch1_2.Text.Length > 0 && txtMatch2_2.Text.Length > 0 && txtMatch3_2.Text.Length > 0) { if (validateMatchQuestion()) { ensureBPUsed ebpu = new ensureBPUsed("Match"); DialogResult result = ebpu.ShowDialog(this); if (result == System.Windows.Forms.DialogResult.Yes) { if (saveQuestion("Match")) { MessageBox.Show("Question has been saved."); ontoNewQuestion(true); saved = true; } else { MessageBox.Show("There is a problem and the question has not been saved."); } } } } else { MessageBox.Show("You must enter items in each of the three columns: \n\n Column 1 \n Letter of Answer \n Column 2 80 \n\nfor at least two different sets of information. \n\n\nPlease use the top two rows for your entries."); } } else { MessageBox.Show("You must enter text to describe the items in Column 2 in the textbox provided."); } } else { MessageBox.Show("You must enter text to describe the items in Column 1 in the textbox provided."); } return saved; } private void determineIfQuizComplete(string lessonTitle) { try { dsCAITTableAdapters.QuizTableAdapter qta = new MasterProject.dsCAITTableAdapters.QuizTableAdapter(); dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); int id = Convert.ToInt32(lta.GetLessonIdFromTitle(lessonTitle)); dsCAIT.QuizDataTable qdt = qta.getQuestionTypesFromLessonId(id); string type = ""; string status = ""; ArrayList al = new ArrayList(); for(int i = 0; i < qdt.Rows.Count; i++) { type = qdt.Rows[i].ItemArray[4].ToString(); if (!al.Contains(type)) { al.Add(type); } } if (al.Count > 2) { status = "Complete"; } else { status = "Incomplete"; } lta.UpdateQuizStatus(status, id); } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } 81 } #endregion #region Events private void btnSave_Click(object sender, EventArgs e) { bool saved = false; if (tbctrlQuestions.SelectedTab == tbMC) { // tab MC saved = saveMCQuestion(); } else if (tbctrlQuestions.SelectedTab == tbTF) { //tab T/F saved = saveTFQuestion(); } else { //tab Match saved = saveMatchQuestion(); } determineIfQuizComplete(this.lblLessonName.Text); if (mode.Equals("Edit") && saved) { this.Close(); } } private void btnCancel_Click(object sender, EventArgs e) { this.Close(); } private void btnFinish_Click(object sender, EventArgs e) { bool valid = shouldSave(); if (valid) { this.Close(); } } private void tbctrlQuestions_Deselecting(object sender, TabControlCancelEventArgs e) { bool valid = shouldSave(); if (!valid) { e.Cancel = true; ; } } private void btnReset_Click(object sender, EventArgs e) 82 { ontoNewQuestion(false); } private void AddQuestion_FormClosed(object sender, FormClosedEventArgs e) { Program.addQuestionOpen = false; } #endregion } } /********************************************************************* * Author: Suzanne Minton * File: Attachment.cs * Date: 2008-2009 * Description: Page for managing attachments * *******************************************************************/ using using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; System.IO; namespace MasterProject { public partial class Attachment : Form { #region Variables private string linkName; private string linkFile; private string linkDescription; private string attachmentType; private byte[] fileAttachment; #endregion #region Properties public string LinkName { get { return linkName; } set { linkName = value; } } public string LinkDescription { get { 83 return linkDescription; } set { linkDescription = value; } } public string AttachmentType { get { return attachmentType; } } public byte [] FileAttachment { get { return this.fileAttachment; } } #endregion #region Constructors public Attachment() { InitializeComponent(); Program.attachmentsOpen = true; txtLinkPath.Enabled = false; btnBrowse.Enabled = true; txtLinkPath.Text = ""; } #endregion #region Methods #endregion #region Events private void btnBrowse_Click(object sender, EventArgs e) { openBrowsedFile.Title = "Select a file"; openBrowsedFile.Filter = "Text files(*.doc;*.txt)|*.doc;*.txt|Image Files(*.bmp;*.jpg;*.gif;*.pdf)|*.bmp;*.jpg;*.gif;*.pdf;*.tif;*.tiff;*.giff|Exce l Files(*.xls)|*.xls;*.xslt"; if (openBrowsedFile.ShowDialog() == DialogResult.OK) { if (txtLinkName.Text == null || "".Equals(txtLinkName.Text)) { MessageBox.Show("Please enter a link name"); } else { txtLinkPath.Text = openBrowsedFile.FileName; } } 84 } private void btnSave_Click(object sender, EventArgs e) { LinkName = txtLinkName.Text; string LinkFile = txtLinkPath.Text; Stream str; if (File.Exists(LinkFile)) { str = openBrowsedFile.OpenFile(); this.fileAttachment = new Byte[str.Length]; str.Read(this.fileAttachment, 0, (int)str.Length); //add the file extension to the file name LinkName += openBrowsedFile.SafeFileName.Substring(openBrowsedFile.SafeFileName.IndexOf("." )); } LinkDescription = txtLinkDesc.Text; if ((LinkName == null || "".Equals(LinkName)) && (LinkFile == null || "".Equals(LinkFile))) MessageBox.Show("Please enter a link name and then browse for a file by clicking the Browse button."); else if (LinkFile == null || "".Equals(LinkFile)) MessageBox.Show("Please browse for a file by clicking the Browse button."); else if (LinkName == null || "".Equals(LinkName)) MessageBox.Show("Please enter a link name."); else this.DialogResult = DialogResult.OK; } private void btnCancel_Click(object sender, EventArgs e) { this.Close(); } private void Attachment_FormClosed(object sender, FormClosedEventArgs e) { Program.attachmentsOpen = false; } #endregion } } /********************************************************************* * Author: Suzanne Minton * File: CAIT.cs * Date: 2008-2009 * Description: Page for holding Master Form *********************************************************************/ using System; using System.Collections.Generic; 85 using using using using using System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; namespace MasterProject { public partial class CAIT : Form { public CAIT() { InitializeComponent(); // Create a new instance of the child form. MasterProject.MainMenu child = new MasterProject.MainMenu(this); // Show the form child.Show(); } } } /********************************************************************* * Author: Suzanne Minton * File: ChangeLessonOrder.cs * Date: 2008-2009 * Description: Page for changing the lessons order *********************************************************************/ using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace MasterProject { public partial class ChangeLessonOrder : Form { #region Constructor public ChangeLessonOrder() { InitializeComponent(); Program.changeLessonOrderOpen = true; } #endregion #region Initializer private void ChangeLessonOrder_Load(object sender, EventArgs e) { // TODO: This line of code loads data into the 'dsCAIT.Lesson' table. You can move, or remove it, as needed. this.lessonTableAdapter.FillLessonDatatable(this.dsCAIT.Lesson); } 86 #endregion #region Methods private void callDBToChangeLessonNumber(int lessonNum, int lessonID) { try { dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); int result = lta.UpdateLessonNumber(lessonNum, lessonID); } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } private void fillLessonList() { this.grdLessons.DataSource = this.lessonTableAdapter.ReturnLessonDatatable(); } #endregion #region Events private void getTitlesToolStripButton_Click(object sender, EventArgs e) { try { this.lessonTableAdapter.GetTitles(this.dsCAIT.Lesson); } catch (System.Exception ex) { System.Windows.Forms.MessageBox.Show(ex.Message); } } private void ChangeLessonOrder_FormClosed(object sender, FormClosedEventArgs e) { Program.changeLessonOrderOpen = false; } private void btnExit_Click(object sender, EventArgs e) { this.Close(); } private void lnkMoveUp_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { if (grdLessons.SelectedRows.Count > 0) { DataGridViewRow selectedRow = grdLessons.SelectedRows[0]; int origLessonNum = (int)selectedRow.Cells["lessonNumberDataGridViewTextBoxColumn"].Value; 87 try { if (origLessonNum > 1) { int origLessonID = (int)selectedRow.Cells["lessonIdDataGridViewTextBoxColumn"].Value; origLessonNum--; int changedLessonNumber = (int)grdLessons.Rows[origLessonNum 1].Cells["lessonNumberDataGridViewTextBoxColumn"].Value; changedLessonNumber++; int changedLessonID = (int)grdLessons.Rows[origLessonNum 1].Cells["lessonIdDataGridViewTextBoxColumn"].Value; callDBToChangeLessonNumber(changedLessonNumber, changedLessonID); callDBToChangeLessonNumber(origLessonNum, origLessonID); fillLessonList(); this.grdLessons.Rows[origLessonNum - 1].Selected = true; this.grdLessons.CurrentCell = this.grdLessons.Rows[origLessonNum - 1].Cells[3]; } else { MessageBox.Show("Lesson can not be moved up."); } } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } } private void lnkMoveDown_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { if (grdLessons.SelectedRows.Count > 0) { DataGridViewRow selectedRow = grdLessons.SelectedRows[0]; int origLessonNum = (int)selectedRow.Cells["lessonNumberDataGridViewTextBoxColumn"].Value; try { if (origLessonNum < grdLessons.Rows.Count) { int origLessonID = (int)selectedRow.Cells["lessonIdDataGridViewTextBoxColumn"].Value; origLessonNum++; 88 int changedLessonNumber = (int)grdLessons.Rows[origLessonNum 1].Cells["lessonNumberDataGridViewTextBoxColumn"].Value; changedLessonNumber--; int changedLessonID = (int)grdLessons.Rows[origLessonNum 1].Cells["lessonIdDataGridViewTextBoxColumn"].Value; callDBToChangeLessonNumber(changedLessonNumber, changedLessonID); callDBToChangeLessonNumber(origLessonNum, origLessonID); fillLessonList(); this.grdLessons.Rows[origLessonNum - 1].Selected = true; this.grdLessons.CurrentCell = this.grdLessons.Rows[origLessonNum - 1].Cells[3]; } else { MessageBox.Show("Lesson can not be moved down."); } } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } } #endregion } } /********************************************************************* * Author: Suzanne Minton * File: EnsureBPUsed.cs * Date: 2008-2009 * Description: Page for ensuring that the best practices for Computer * Assisted Instruction are used by the Instructor *********************************************************************/ using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; namespace MasterProject { public partial class ensureBPUsed : Form { #region Constructor public ensureBPUsed(string type) 89 { InitializeComponent(); if (type.Equals("TF")) { this.rtxtBeenMetVariable.Text = "Before confirming that you want to save this true or false question, please ensure that the following guidelines have been met:"; this.chLBList.Items.Add("This statement tests the student's recall or confirmation ability"); this.chLBList.Items.Add("This statement centers on an important concept from the lesson"); this.chLBList.Items.Add("This statement is a fact, not an opinion"); this.chLBList.Items.Add("There is an explanation for why this statement is true or false"); this.chLBList.Items.Add("The student cannot interpret this statement as being both true and false"); } else if (type.Equals("MC")) { this.rtxtBeenMetVariable.Text = "Before confirming that you want to save this mulitple choice question, please ensure that the following guidelines have been met:"; this.chLBList.Items.Add("Each choice is seemingly valid"); this.chLBList.Items.Add("Each incorrect choice has something in common with the correct choice"); this.chLBList.Items.Add("There is an explanation for each incorrect choice"); this.chLBList.Items.Add("All of the choices are distinguishable from each other"); this.chLBList.Items.Add("There are no ambiguous choices, wording is stated in an active voice"); } else if (type.Equals("Match")) { rtxtBeenMetVariable.Text = "Before confirming that you want to save this match question, please ensure that the following guidelines have been met:"; this.chLBList.Items.Add("The question measures the student's ability to identify the relationship between a set of similar items"); this.chLBList.Items.Add("Each of the items in Column 1 are homogeneous, or similar to each other"); this.chLBList.Items.Add("Each of the items in Column 2 are homogeneous, or similar to each other"); this.chLBList.Items.Add("There is not more than one item in Column 2 that can match an item in Column 1 and vice versa"); this.chLBList.Items.Add("You have considered the reccommendation that you only use five to eight items in each column"); this.chLBList.Items.Add("There are the same number of items in Column 1 as there are in Column 2"); this.chLBList.Items.Add("The item with more words is in Column 2, not Column 1"); } else if (type.Equals("Lesson")) { rtxtBeenMetVariable.Text = "Before confirming that you want to save this lesson, please ensure that the following guidelines have been met:"; this.chLBList.Items.Add("You have read the Best Practices guidelines and complied with them."); 90 this.chLBList.Items.Add("This lesson only contains one concept."); this.chLBList.Items.Add("To avoid presenting too much info at one time you tried to keep the lesson to 23 lines or less."); this.chLBList.Items.Add("You have or plan to create a title page for this lesson."); this.chLBList.Items.Add("You have or plan to create a quiz for this lesson."); this.chLBList.Items.Add("You have specified the places in the text where you want the student to view each attachment."); this.chLBList.Items.Add("This lesson has been placed in an order that makes sense in relation to prior lessons."); } else { MessageBox.Show("Problem with type"); } } #endregion #region Events private void btnYes_Click(object sender, EventArgs e) { this.Close(); } private void btnNo_Click(object sender, EventArgs e) { this.Close(); } private void chLBList_SelectedIndexChanged(object sender, EventArgs e) { if (chLBList.Items.Count == chLBList.CheckedItems.Count) { btnYes.Enabled = true; } else { btnYes.Enabled = false; } } #endregion } } /********************************************************************* * Author: Suzanne Minton * File: FileManager.cs * Date: 2008-2009 * Description: Class for managing files *********************************************************************/ using using using using using System; System.Collections.Generic; System.Text; System.IO; System.Windows.Forms; 91 namespace MasterProject { class FileManager { #region Methods public bool saveLesson(string title, string lessonText) { dsCAITTableAdapters.LessonTableAdapter _taLesson = null; bool saveSuccessful = false; bool isNewFile = false; string filePath = "C:\\Temp\\Lessons"; string fileName = filePath + "\\" + title + ".doc"; try { DirectoryInfo dirInfo = new DirectoryInfo(filePath); if (!dirInfo.Exists) { try { dirInfo.Create(); } catch (Exception ex) { MessageBox.Show("There was a problem creating the directory."); } } else { Console.WriteLine("Directory already exists."); } try { FileStream fs; FileInfo fileInfo = new FileInfo(fileName); if (!fileInfo.Exists) { isNewFile = true; fs = new FileStream(fileName, FileMode.CreateNew); } else { isNewFile = false; fs = new FileStream(fileName, FileMode.Truncate); } StreamWriter sw = new StreamWriter(fs); sw.WriteLine(lessonText); sw.Close(); fs.Close(); } catch (Exception ex) { MessageBox.Show("There was a problem with the file system."); 92 } saveSuccessful = true; } catch (Exception ex) { MessageBox.Show("There was a problem with the file and directory system."); } return saveSuccessful; } public bool deleteLesson(string title) { dsCAITTableAdapters.LessonTableAdapter _taLesson = null; dsCAITTableAdapters.QuizTableAdapter _taQuiz = null; dsCAITTableAdapters.TitlePageTableAdapter _taTitlePage = null; dsCAITTableAdapters.LessonStatusTableAdapter _taLessonStatus = null; dsCAITTableAdapters.AttachmentTableAdapter _taAttachment = null; bool deleteSuccessful = false; string filePath = "C:\\Temp\\Lessons"; string fileName = filePath + "\\" + title + ".doc"; try { FileInfo fileInfo = new FileInfo(fileName); if (fileInfo.Exists) { fileInfo.Delete(); _taLesson = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); int id = Convert.ToInt32(_taLesson.GetLessonIdFromTitle(title)); _taAttachment = new MasterProject.dsCAITTableAdapters.AttachmentTableAdapter(); _taAttachment.DeleteByLessonID(id); _taLesson.DeleteLesson(id); _taQuiz = new MasterProject.dsCAITTableAdapters.QuizTableAdapter(); _taQuiz.DeleteQuiz(id); _taTitlePage = new MasterProject.dsCAITTableAdapters.TitlePageTableAdapter(); _taTitlePage.DeleteTitlePage(id); _taLessonStatus = new MasterProject.dsCAITTableAdapters.LessonStatusTableAdapter(); _taLessonStatus.DeleteLessonStatus(id); deleteSuccessful = true; } } catch (Exception ex) { MessageBox.Show("There was a problem deleting the lesson, title page, and/or quiz"); } 93 return deleteSuccessful; } public string viewLesson(string title) { string filePath = "C:\\Temp\\Lessons"; string fileName = filePath + "\\" + title + ".doc"; string text = ""; try { FileStream fs = new FileStream(fileName, FileMode.Open); StreamReader sr = new StreamReader(fs); string tempText = sr.ReadLine(); while (tempText != null) { text += tempText + "\n"; tempText = sr.ReadLine(); } sr.Close(); fs.Close(); } catch (Exception ex) { MessageBox.Show("There was a problem opening or reading the file."); } return text; } public bool updateLessonTitle(string oldTitle, string newTitle) { bool updateSuccessful = false; string oldLessonText = viewLesson(oldTitle); try { if (saveLesson(newTitle, oldLessonText)) { if (deleteLesson(oldTitle)) { updateSuccessful = true; } else { MessageBox.Show("There was a problem deleting the old lesson title's file."); } } else { MessageBox.Show("There was a problem changing the lesson's file name."); } } catch (Exception ex) { MessageBox.Show("There was a problem changing the lesson's file name."); 94 } return updateSuccessful; } public void openFile(bool isBestPractice) { string filePath = "C:\\Temp\\"; string fileName = filePath; if (isBestPractice) { fileName += "Best Practices.doc"; } else { if (MainMenu.getUserType().Equals("Student")) { fileName += "StudentHelp.doc"; } else { fileName += "InstructorHelp.doc"; } } DirectoryInfo dirInfo = new DirectoryInfo(filePath); if (!dirInfo.Exists) { MessageBox.Show("There was a problem accessing the directory: " + filePath, "Error"); } else { try { System.Diagnostics.Process.Start(fileName); } catch (Exception ex) { MessageBox.Show("There was a problem accessing the file: " + fileName, "Error"); } } } #endregion } } /********************************************************************* * Author: Suzanne Minton * File: GetNewLessonTitle.cs * Date: 2008-2009 * Description: Page for changing the lesson title *********************************************************************/ using System; 95 using using using using using using using System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; System.Text.RegularExpressions; namespace MasterProject { public partial class GetNewLessonTitle : Form { #region Declarations private string _mode = ""; private string _oldLessonTitle; #endregion #region Constructor public GetNewLessonTitle() { _mode = "New Lesson"; InitializeComponent(); Program.getNewLessonTitle = true; } public GetNewLessonTitle(string oldLessonTitle) { _mode = "New Title"; _oldLessonTitle = oldLessonTitle; InitializeComponent(); Program.getNewLessonTitle = true; this.Text = "Old Lesson Title: " + oldLessonTitle; btnContinue.Text = "Save New Title"; } #endregion #region Methods private bool saveLessonTitle() { bool saveSuccessful = false; dsCAITTableAdapters.LessonTableAdapter _taLesson = null; if (txtLessonTitle.TextLength >= 1) { if (IsAlphaNumeric(txtLessonTitle.Text)) { bool titleFound = false; dsCAIT.LessonDataTable dtLesson = null; try { dsCAITTableAdapters.LessonTableAdapter _lessonTableAdapter = new dsCAITTableAdapters.LessonTableAdapter(); dtLesson = _lessonTableAdapter.ReturnLessonDatatable(); } catch (Exception ex) { 96 MessageBox.Show("There was a problem with the database."); } foreach (DataRow row in dtLesson) { if (row.ItemArray.GetValue(0).ToString().Equals(txtLessonTitle.Text)) { titleFound = true; break; } } if (!titleFound) //Title doesn't exist in database yet { try { _taLesson = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); if (_mode.Equals("New Lesson")) { int maxLessonNumber = 0; object o = _taLesson.maxLessonNumber(); if (o != null) { maxLessonNumber = Convert.ToInt32(o); } _taLesson.InsertTitle(txtLessonTitle.Text, maxLessonNumber + 1); } else { int id = Convert.ToInt32(_taLesson.GetLessonIdFromTitle(_oldLessonTitle)); _taLesson.UpdateLessonTitle(txtLessonTitle.Text, id); FileManager fm = new FileManager(); fm.updateLessonTitle(_oldLessonTitle, txtLessonTitle.Text); } saveSuccessful = true; } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } if (saveSuccessful) //Save lesson to db { saveSuccessful = true; } else { 97 MessageBox.Show("There was an error saving your lesson."); } } else { MessageBox.Show("This title has already been used for another lesson."); } } else { MessageBox.Show("All of the characters in the title must be either a letter or a number."); } } else //No input in text field { if (txtLessonTitle.TextLength < 1 && txtLessonTitle.TextLength < 1) { MessageBox.Show("Please enter a title and text."); } else if (txtLessonTitle.TextLength < 1) { MessageBox.Show("Please enter a title."); } else { MessageBox.Show("Please enter text."); } } return saveSuccessful; } private bool IsAlphaNumeric(String str) { Regex regexAlphaNum = new Regex("[^a-zA-Z0-9 ]"); return !regexAlphaNum.IsMatch(str); } #endregion #region Events private void btnContinue_Click(object sender, EventArgs e) { if (_mode.Equals("New Lesson") && saveLessonTitle()) { // Goes to AddEditLesson if (!Program.addEditLessonOpen) { Program.isTempLesson = true; AddEditLesson ael = new AddEditLesson(); ael.Show(); this.Close(); } else { 98 MessageBox.Show("You already have a lesson opened."); } } else { saveLessonTitle(); this.Close(); } } private void btnCancel_Click(object sender, EventArgs e) { this.Close(); } private void GetNewLessonTitle_FormClosed(object sender, FormClosedEventArgs e) { Program.getNewLessonTitle = false; } #endregion } } /********************************************************************* * Author: Suzanne Minton * File: LessonStatus.cs * Date: 2008-2009 * Description: Page for updating lesson status *********************************************************************/ using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; namespace MasterProject { public partial class LessonStatus : Form { #region Variables bool lessonStatusExists = false; #endregion #region Constructors public LessonStatus(string lessonTitle) { InitializeComponent(); this.lblLessonName.Text = lessonTitle; populateCheckBoxes(lessonTitle); Program.lessonStatusOpen = true; } #endregion #region Methods 99 private void populateCheckBoxes(string lessonTitle) { try { dsCAITTableAdapters.LessonStatusTableAdapter lsta = new MasterProject.dsCAITTableAdapters.LessonStatusTableAdapter(); dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); int id = Convert.ToInt32(lta.GetLessonIdFromTitle(lessonTitle)); dsCAIT.LessonStatusDataTable lsdt = lsta.retrieveLessonStatusFromLessonId(id); if (lsdt.Rows.Count > 0) { lessonStatusExists = true; if (lsdt.Rows[0].ItemArray[1].ToString().Trim().ToUpper().Equals("TRUE")) { cbxOrderLessons.Checked = true; } if (lsdt.Rows[0].ItemArray[2].ToString().Trim().ToUpper().Equals("TRUE")) { cbxOneConcept.Checked = true; } if (lsdt.Rows[0].ItemArray[3].ToString().Trim().ToUpper().Equals("TRUE")) { cbxGoodExplanation.Checked = true; } if (lsdt.Rows[0].ItemArray[4].ToString().Trim().ToUpper().Equals("TRUE")) { cbxExamplesGiven.Checked = true; } if (lsdt.Rows[0].ItemArray[5].ToString().Trim().ToUpper().Equals("TRUE")) { cbxCreateQuiz.Checked = true; } if (lsdt.Rows[0].ItemArray[6].ToString().Trim().ToUpper().Equals("TRUE")) { cbxTitlePage.Checked = true; } } } catch (Exception ex) { MessageBox.Show("There was a problem retreiving the lesson status from the database."); } } #endregion 100 #region Events private void btnCancel_Click(object sender, EventArgs e) { this.Close(); } private void btnSave_Click(object sender, EventArgs e) { dsCAITTableAdapters.LessonStatusTableAdapter lsta = new MasterProject.dsCAITTableAdapters.LessonStatusTableAdapter(); dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); try { int id = Convert.ToInt32(lta.GetLessonIdFromTitle(lblLessonName.Text)); if (lessonStatusExists) { lsta.UpdateLessonStatus(cbxOrderLessons.Checked.ToString(), cbxOneConcept.Checked.ToString(), cbxGoodExplanation.Checked.ToString(), cbxExamplesGiven.Checked.ToString(), cbxCreateQuiz.Checked.ToString(), cbxTitlePage.Checked.ToString(), id); } else { lsta.InsertLessonStatus(cbxOrderLessons.Checked.ToString(), cbxOneConcept.Checked.ToString(), cbxGoodExplanation.Checked.ToString(), cbxExamplesGiven.Checked.ToString(), cbxCreateQuiz.Checked.ToString(), cbxTitlePage.Checked.ToString(), id); } MessageBox.Show("Lesson Status saved successfully.", "Saved"); this.Close(); } catch (Exception ex) { MessageBox.Show("There was a problem saving the lesson status."); } } private void LessonStatus_FormClosed(object sender, FormClosedEventArgs e) { Program.lessonStatusOpen = false; } #endregion } } /********************************************************************* * Author: Suzanne Minton * File: Login.cs * Date: 2008-2009 * Description: Page for logging into CAIT *********************************************************************/ 101 using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; namespace MasterProject { public partial class Login : Form { #region Constructor public Login() { InitializeComponent(); } #endregion #region Events private void btnEnter_Click(object sender, EventArgs e) { dsCAITTableAdapters.LoginInfoTableAdapter _loginInfoTableAdapter = new dsCAITTableAdapters.LoginInfoTableAdapter(); if (rbInstructor.Checked) { if (txtPsswd.Text.Equals("i")) { try { // Save instructor value to db _loginInfoTableAdapter.InsertLogin(DateTime.Now, "Instructor"); this.Close(); } catch (Exception ex) { MessageBox.Show("Cannot connect to the database."); } } else { MessageBox.Show("Password entered is wrong."); } } else if (rbStudent.Checked) { try { // Save student value to db _loginInfoTableAdapter.InsertLogin(DateTime.Now, "Student"); this.Close(); // dsCAIT.LoginInfoDataTable dtLoginInfo = _loginInfoTableAdapter.GetLogins(); 102 } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } } private void rbInstructor_CheckedChanged(object sender, EventArgs e) { if (rbInstructor.Checked || rbStudent.Checked) { btnEnter.Enabled = true; } else { btnEnter.Enabled = false; } } private void rbStudent_CheckedChanged(object sender, EventArgs e) { if (rbInstructor.Checked || rbStudent.Checked) { btnEnter.Enabled = true; } else { btnEnter.Enabled = false; } } private void btnExitCAIT_Click(object sender, EventArgs e) { Program.continueToCAIT = false; this.Close(); } #endregion } } /********************************************************************* * Author: Suzanne Minton * File: MainMenu.cs * Date: 2008-2009 * Description: Page for the main menu of CAIT *********************************************************************/ using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; namespace MasterProject { public partial class MainMenu : Form { 103 #region Declarations string userType = ""; #endregion #region Constructors public MainMenu(MasterProject.CAIT parent) { InitializeComponent(); //Set the parent of the form to the container this.MdiParent = parent; //Set up the page initialSetUp(); } public MainMenu() { InitializeComponent(); //Set up the page initialSetUp(); } #endregion #region Initializers private void MainMenu_Load(object sender, EventArgs e) { // TODO: This line of code loads data into the 'dsCAIT.Lesson' table. You can move, or remove it, as needed. this.lessonTableAdapter.FillLessonDatatable(this.dsCAIT.Lesson); } #endregion #region Methods public static string getUserType() { dsCAITTableAdapters.LoginInfoTableAdapter _loginInfoTableAdapter = new dsCAITTableAdapters.LoginInfoTableAdapter(); string returnUserType = ""; try { dsCAIT.LoginInfoDataTable dtLoginInfo = _loginInfoTableAdapter.GetSortedData(); returnUserType = dtLoginInfo.Rows[0].ItemArray.GetValue(1).ToString(); } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } return returnUserType; } private void initialSetUp() { //Set up list box with Lesson Names 104 lbxLessons.DisplayMember = "Title"; lbxLessons.ValueMember = "Title"; dsCAITTableAdapters.LessonTableAdapter _taLesson = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); lbxLessons.DataSource = _taLesson.ReturnLessonDatatable(); lbxTitlePages.DisplayMember = "Title"; lbxTitlePages.ValueMember = "Title"; lbxTitlePages.DataSource = _taLesson.ReturnLessonDatatable(); userType = getUserType(); //If userType is student only display view lesson and view quiz if (userType.Equals("Student")) { lblReadlessonFirst.Visible = true; btnNew.Visible = false; btnEdit.Visible = false; btnDelete.Visible = false; btnChangeLessonName.Visible = false; lnkRefresh.Visible = false; btnLessonStatus.Visible = false; btnChangeLessonOrder.Visible = false; lnkBestPractices.Visible = false; //Remove this after testing lnkHelpPage.Visible = false; if (tbctrlMainMenu.TabCount > 1) { tbQuizzes.Hide(); tbTitlePages.Hide(); tbctrlMainMenu.TabPages.Remove(tbQuizzes); tbctrlMainMenu.TabPages.Remove(tbTitlePages); } } } #endregion #region Events private void btnNew_Click(object sender, EventArgs e) { // Goes to GetNewLessonTitle if (!Program.getNewLessonTitle) { GetNewLessonTitle gnlt = new GetNewLessonTitle(); gnlt.Show(); } else { MessageBox.Show("You already have a lesson opened."); } } private void btnDelete_Click(object sender, EventArgs e) { 105 if (lbxLessons.SelectedValue != null) { DialogResult result; // Displays the MessageBox. result = MessageBox.Show("Are you sure you want to delete this lesson and its corresponding title page and quiz?", "Delete Lesson", MessageBoxButtons.YesNo); if (result == System.Windows.Forms.DialogResult.Yes) { FileManager fm = new FileManager(); if (fm.deleteLesson(lbxLessons.SelectedValue.ToString())) { MessageBox.Show("Lesson and Quiz Deleted"); initialSetUp(); lessonTableAdapter.FillLessonDatatable(dsCAIT.Lesson); lessonBindingSource.DataSource = dsCAIT.Lesson; this.grdQuizes.DataSource = lessonBindingSource; } else { MessageBox.Show("There was an error deleting your lesson."); } } } else { MessageBox.Show("Please select a lesson to delete."); } } private void btnEdit_Click(object sender, EventArgs e) { // Goes to AddEditLesson if (!Program.addEditLessonOpen) { dsCAIT.LessonDataTable ldt; dsCAITTableAdapters.LessonTableAdapter _LessonsDA = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); ldt = _LessonsDA.GetLessonByTitle(lbxLessons.SelectedValue.ToString()); AddEditLesson ael = new AddEditLesson(lbxLessons.SelectedValue.ToString(), Convert.ToInt32(ldt.Rows[0]["LessonID"])); ael.Show(); } else { MessageBox.Show("You already have a lesson opened."); } } private void btnView_Click(object sender, EventArgs e) { if (!Program.viewLessonOpen && !Program.viewTitlePage) { if (lbxLessons.SelectedValue != null) { 106 try { dsCAIT.LessonDataTable ldt; dsCAITTableAdapters.LessonTableAdapter _LessonsDA = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); ldt = _LessonsDA.GetLessonByTitle(lbxLessons.SelectedValue.ToString()); int id = Convert.ToInt32(ldt.Rows[0]["LessonID"]); ViewLesson vl = new ViewLesson(lbxLessons.SelectedValue.ToString(), id); vl.Show(); dsCAITTableAdapters.TitlePageTableAdapter tpta = new MasterProject.dsCAITTableAdapters.TitlePageTableAdapter(); object tmp = tpta.TitlePageExists(id); if (tmp != null && (int)tmp == 1) { ViewTitlePage vtp = new ViewTitlePage(lbxLessons.SelectedValue.ToString()); vtp.Show(); } } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } else { MessageBox.Show("Please select a lesson to view."); } } else { MessageBox.Show("You already have a lesson opened."); } } private void lnkRefresh_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { initialSetUp(); lessonTableAdapter.FillLessonDatatable(dsCAIT.Lesson); lessonBindingSource.DataSource = dsCAIT.Lesson; this.grdQuizes.DataSource = lessonBindingSource; } private void lnkExit_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { this.Close(); CAIT.ActiveForm.Close(); } private void lnkLogout_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { 107 ReLogin reloginScreen = new ReLogin(); reloginScreen.Show(); this.Close(); } private void btnAddEditQuiz_Click(object sender, EventArgs e) { if ((grdQuizes.SelectedRows.Count > 0) && !(grdQuizes.SelectedRows[0].Cells[0].Value.ToString().Equals(""))) { if (!Program.addEditQuizOpen) { string title = grdQuizes.SelectedRows[0].Cells[0].Value.ToString(); AddEditQuiz aeq = new AddEditQuiz(title); aeq.Show(); } else { MessageBox.Show("You already have a quiz opened."); } } } private void btnDeleteQuiz_Click(object sender, EventArgs e) { if ((grdQuizes.SelectedRows.Count > 0) && !(grdQuizes.SelectedRows[0].Cells[0].Value.ToString().Equals(""))) { string title = grdQuizes.SelectedRows[0].Cells[0].Value.ToString(); try { DialogResult result = MessageBox.Show("Are you sure you want to delete this quiz's contents?", "Delete Quiz Contents", MessageBoxButtons.YesNo); if (result == System.Windows.Forms.DialogResult.Yes) { dsCAITTableAdapters.QuizTableAdapter _taQuiz = null; _taQuiz = new MasterProject.dsCAITTableAdapters.QuizTableAdapter(); dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); int id = Convert.ToInt32(lta.GetLessonIdFromTitle(title)); _taQuiz.DeleteQuiz(id); lta.UpdateQuizStatus("Incomplete", id); initialSetUp(); lessonTableAdapter.FillLessonDatatable(dsCAIT.Lesson); lessonBindingSource.DataSource = dsCAIT.Lesson; this.grdQuizes.DataSource = lessonBindingSource; } } catch (Exception ex) { 108 MessageBox.Show("There was a problem deleting the quiz contents."); } } } private void btnCreateTitlePage_Click(object sender, EventArgs e) { if (!Program.titlePageCreationOpen) { // Goes to TitlePageCreation TitlePageCreation tpc = new TitlePageCreation(lbxTitlePages.SelectedValue.ToString()); tpc.Show(); } else { MessageBox.Show("You already have title page creation opened."); } } private void lnkHelpPage_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { FileManager fman = new FileManager(); fman.openFile(false); } private void btnLessonStatus_Click(object sender, EventArgs e) { if (!Program.lessonStatusOpen) { LessonStatus ls = new LessonStatus(lbxLessons.SelectedValue.ToString()); ls.Show(); } else { MessageBox.Show("You already have lesson status opened."); } } private void lnkBestPractices_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { FileManager fman = new FileManager(); fman.openFile(true); } private void btnChangeLessonOrder_Click(object sender, EventArgs e) { if (!Program.changeLessonOrderOpen) { ChangeLessonOrder clo = new ChangeLessonOrder(); clo.Show(); } else { 109 MessageBox.Show("You already have change lesson order opened."); } } private void btnTakeQuiz_Click(object sender, EventArgs e) { if (!Program.takeQuizOpen) { TakeQuiz tq = new TakeQuiz(lbxLessons.SelectedValue.ToString()); if (tq.getNumberOfQuestions(lbxLessons.SelectedValue.ToString()) > 0) { tq.Show(); } else { MessageBox.Show("A quiz has not been created for this lesson yet.", "Error"); } } else { MessageBox.Show("You are already have take quiz opened."); } } private void btnChangeLessonName_Click(object sender, EventArgs e) { if (!Program.getNewLessonTitle) { GetNewLessonTitle gnlt = new GetNewLessonTitle(lbxLessons.SelectedValue.ToString()); gnlt.Show(); } else { MessageBox.Show("You already have a change lesson title opened."); } } #endregion } } /********************************************************************* * Author: Suzanne Minton * File: Program.cs * Date: 2008-2009 * Description: Main program class for CAIT *********************************************************************/ using System; using System.Collections.Generic; 110 using using using using System.Windows.Forms; System.Data; System.Data.SqlClient; System.Text; namespace MasterProject { static class Program { public static bool continueToCAIT = true; public static bool addEditLessonOpen = false; public static bool addEditQuizOpen = false; public static bool addQuestionOpen = false; public static bool attachmentsOpen = false; public static bool lessonStatusOpen = false; public static bool titlePageCreationOpen = false; public static bool viewLessonOpen = false; public static bool changeLessonOrderOpen = false; public static bool takeQuizOpen = false; public static bool viewTitlePage = false; public static bool getNewLessonTitle = false; public static bool isTempLesson = false; public static bool okToCloseLesson = false; public static string LessonsFolder = ""; public static string LessonsAttachmentsFolder = ""; /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Login()); if (continueToCAIT) { Application.Run(new CAIT()); } } } } /********************************************************************* * Author: Suzanne Minton * File: ReLogin.cs * Date: 2008-2009 * Description: Page for relogging into CAIT *********************************************************************/ using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; 111 namespace MasterProject { public partial class ReLogin : Form { #region Constructor public ReLogin() { InitializeComponent(); btnEnter.Enabled = false; } #endregion #region Events private void btnEnter_Click(object sender, EventArgs e) { dsCAITTableAdapters.LoginInfoTableAdapter _loginInfoTableAdapter = new dsCAITTableAdapters.LoginInfoTableAdapter(); if (rbInstructor.Checked) { if (txtPsswd.Text.Equals("i")) { try { // Save instructor value to db _loginInfoTableAdapter.InsertLogin(DateTime.Now, "Instructor"); MainMenu mm = new MainMenu(); mm.Show(); this.Close(); } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } else { MessageBox.Show("Password entered is wrong."); } } else if (rbStudent.Checked) { try { // Save student value to db _loginInfoTableAdapter.InsertLogin(DateTime.Now, "Student"); MainMenu mm = new MainMenu(); mm.Show(); this.Close(); } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } } 112 private void rbInstructor_CheckedChanged(object sender, EventArgs e) { if (rbInstructor.Checked || rbStudent.Checked) { btnEnter.Enabled = true; } else { btnEnter.Enabled = false; } } private void rbStudent_CheckedChanged(object sender, EventArgs e) { if (rbInstructor.Checked || rbStudent.Checked) { btnEnter.Enabled = true; } else { btnEnter.Enabled = false; } } private void btnExitCAIT_Click(object sender, EventArgs e) { this.Close(); CAIT.ActiveForm.Close(); } #endregion } } /********************************************************************* * Author: Suzanne Minton * File: TakeQuiz.cs * Date: 2008-2009 * Description: Page for student to take quiz *********************************************************************/ using using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; System.Collections; namespace MasterProject { public partial class TakeQuiz : Form { #region Variables int currQuestionNum; int numOfQuestions; int numAnswersCorrectly; 113 dsCAIT.QuizDataTable currQuestionDataTable; #endregion #region Constructors public TakeQuiz(string lessonName) { InitializeComponent(); currQuestionNum = 1; lblLessonName.Text = lessonName; numOfQuestions = getNumberOfQuestions(lessonName); numAnswersCorrectly = 0; if (numOfQuestions > 0) { lblNumQuestions.Text = numOfQuestions.ToString(); setUpQuestion(); Program.takeQuizOpen = true; } } #endregion #region Methods public int getNumberOfQuestions(string lessonName) { int numQuestions = 0; try { dsCAITTableAdapters.QuizTableAdapter qta = new MasterProject.dsCAITTableAdapters.QuizTableAdapter(); dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); int id = Convert.ToInt32(lta.GetLessonIdFromTitle(lessonName)); object tmpNQ = qta.maxQuestionNumber(id); if (tmpNQ != null) { numQuestions = (int)tmpNQ; } } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } return numQuestions; } private void setUpQuestion() { lblQuestionNumber.Text = currQuestionNum.ToString(); try 114 { dsCAITTableAdapters.QuizTableAdapter qta = new MasterProject.dsCAITTableAdapters.QuizTableAdapter(); dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); int id = Convert.ToInt32(lta.GetLessonIdFromTitle(lblLessonName.Text)); currQuestionDataTable = qta.retrieveQuizQuestionByIdAndNumber(currQuestionNum, id); string questType = currQuestionDataTable.Rows[0].ItemArray[4].ToString(); if (questType.Equals("MC")) { setUpMCQuestion(); } else if (questType.Equals("T/F")) { setUpTFQuestion(); } else { setUpMatchQuestion(); } } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } private void setUpMCQuestion() { if (!tbCtrlQuestions.TabPages.Contains(tbMC)) { tbCtrlQuestions.TabPages.Add(tbMC); } if (tbCtrlQuestions.TabPages.Contains(tbMatch)) { tbCtrlQuestions.TabPages.Remove(tbMatch); } if (tbCtrlQuestions.TabPages.Contains(tbTF)) { tbCtrlQuestions.TabPages.Remove(tbTF); } txtMCQuestion.Text = currQuestionDataTable.Rows[0].ItemArray[2].ToString(); txtPossAnsA.Text = currQuestionDataTable.Rows[0].ItemArray[8].ToString(); txtPossAnsB.Text = currQuestionDataTable.Rows[0].ItemArray[9].ToString(); if (currQuestionDataTable.Rows[0].ItemArray[10] != null && !currQuestionDataTable.Rows[0].ItemArray[10].ToString().Equals("")) { 115 txtPossAnsC.Show(); rbAnsC.Show(); lblCLabel.Show(); txtPossAnsC.Text = currQuestionDataTable.Rows[0].ItemArray[10].ToString(); } else { txtPossAnsC.Hide(); rbAnsC.Hide(); lblCLabel.Hide(); } if (currQuestionDataTable.Rows[0].ItemArray[11] != null && !currQuestionDataTable.Rows[0].ItemArray[11].ToString().Equals("")) { txtPossAnsD.Show(); rbAnsD.Show(); lblDLabel.Show(); txtPossAnsD.Text = currQuestionDataTable.Rows[0].ItemArray[11].ToString(); } else { txtPossAnsD.Hide(); rbAnsD.Hide(); lblDLabel.Hide(); } } private void setUpTFQuestion() { if (!tbCtrlQuestions.TabPages.Contains(tbTF)) { tbCtrlQuestions.TabPages.Add(tbTF); } if (tbCtrlQuestions.TabPages.Contains(tbMatch)) { tbCtrlQuestions.TabPages.Remove(tbMatch); } if (tbCtrlQuestions.TabPages.Contains(tbMC)) { tbCtrlQuestions.TabPages.Remove(tbMC); } txtTFQuestion.Text = currQuestionDataTable.Rows[0].ItemArray[2].ToString(); rbFalse.Checked = false; rbTrue.Checked = false; } private void setUpMatchQuestion() { if (!tbCtrlQuestions.TabPages.Contains(tbMatch)) { tbCtrlQuestions.TabPages.Add(tbMatch); } if (tbCtrlQuestions.TabPages.Contains(tbMC)) { tbCtrlQuestions.TabPages.Remove(tbMC); 116 } if (tbCtrlQuestions.TabPages.Contains(tbTF)) { tbCtrlQuestions.TabPages.Remove(tbTF); } string savedText = currQuestionDataTable.Rows[0].ItemArray[2].ToString(); int place = savedText.IndexOf(";;;"); if (place > 0) { string val1 = savedText.Substring(0, place); string val2 = savedText.Substring(place + 3); string newText = "Please match the " + val1 + " to the " + val2; lblMatchQuestion.Text = newText; } //Populate Column 1 string tmpCol1 = currQuestionDataTable.Rows[0].ItemArray[6].ToString(); //Create Array that contains all values ArrayList alCol1 = new ArrayList(); int i = 0; while (i < tmpCol1.Length) { int tmpPlace = tmpCol1.IndexOf(";;;", i); alCol1.Add(tmpCol1.Substring(i, tmpPlace - i)); i = tmpPlace + 3; } //Set txt boxes to array values if (alCol1.Count > 0) txtMatch1_1.Text = alCol1[0].ToString(); if (alCol1.Count > 1) txtMatch1_2.Text = alCol1[1].ToString(); if (alCol1.Count > 2) txtMatch1_3.Text = alCol1[2].ToString(); if (alCol1.Count > 3) txtMatch1_4.Text = alCol1[3].ToString(); if (alCol1.Count > 4) txtMatch1_5.Text = alCol1[4].ToString(); if (alCol1.Count > 5) txtMatch1_6.Text = alCol1[5].ToString(); if (alCol1.Count > 6) txtMatch1_7.Text = alCol1[6].ToString(); if (alCol1.Count > 7) txtMatch1_8.Text = alCol1[7].ToString(); if (alCol1.Count > 8) txtMatch1_9.Text = alCol1[8].ToString(); if (alCol1.Count > 9) txtMatch1_10.Text = alCol1[9].ToString(); //Populate Column 2 string tmpCol2 = currQuestionDataTable.Rows[0].ItemArray[7].ToString(); //Create Array that contains all values 117 ArrayList alCol2 = new ArrayList(); int i2 = 0; while (i2 < tmpCol2.Length) { int tmpPlace = tmpCol2.IndexOf(";;;", i2); alCol2.Add(tmpCol2.Substring(i2, tmpPlace - i2)); i2 = tmpPlace + 3; } //Set txt boxes to array values if (alCol2.Count > 0) txtMatch3_1.Text = alCol2[0].ToString(); if (alCol2.Count > 1) txtMatch3_2.Text = alCol2[1].ToString(); if (alCol2.Count > 2) txtMatch3_3.Text = alCol2[2].ToString(); if (alCol2.Count > 3) txtMatch3_4.Text = alCol2[3].ToString(); if (alCol2.Count > 4) txtMatch3_5.Text = alCol2[4].ToString(); if (alCol2.Count > 5) txtMatch3_6.Text = alCol2[5].ToString(); if (alCol2.Count > 6) txtMatch3_7.Text = alCol2[6].ToString(); if (alCol2.Count > 7) txtMatch3_8.Text = alCol2[7].ToString(); if (alCol2.Count > 8) txtMatch3_9.Text = alCol2[8].ToString(); if (alCol2.Count > 9) txtMatch3_10.Text = alCol2[9].ToString(); } private void validMCAnswer() { if (rbAnsA.Checked || rbAnsB.Checked || rbAnsC.Checked || rbAnsD.Checked) { if ((currQuestionDataTable.Rows[0].ItemArray[3].ToString().ToUpper().Equals("A") && rbAnsA.Checked) || (currQuestionDataTable.Rows[0].ItemArray[3].ToString().ToUpper().Equals("B") && rbAnsB.Checked) || (currQuestionDataTable.Rows[0].ItemArray[3].ToString().ToUpper().Equals("C") && rbAnsC.Checked) || (currQuestionDataTable.Rows[0].ItemArray[3].ToString().ToUpper().Equals("D") && rbAnsD.Checked)) { MessageBox.Show("Congratulations! You are correct. \n\n" + currQuestionDataTable.Rows[0].ItemArray[5].ToString(), "Good Job"); numAnswersCorrectly++; } else { MessageBox.Show("Sorry! You are incorrect. \n\n" + currQuestionDataTable.Rows[0].ItemArray[5].ToString(), "Incorrect"); } 118 goToNextQuestion(); } else { if (!txtPossAnsD.Text.Equals("")) { MessageBox.Show("You need to choose either A, B, C, or D.", "Error"); } else if (!txtPossAnsC.Text.Equals("")) { MessageBox.Show("You need to choose either A, B, or C.", "Error"); } else { MessageBox.Show("You need to choose either A or B.", "Error"); } } } private void validTFAnswer() { if (rbTrue.Checked || rbFalse.Checked) { if ((currQuestionDataTable.Rows[0].ItemArray[3].ToString().ToUpper().Equals("TRUE" ) && rbTrue.Checked) || (currQuestionDataTable.Rows[0].ItemArray[3].ToString().ToUpper().Equals("FALSE" ) && rbFalse.Checked)) { MessageBox.Show("Congratulations! You are correct. \n\n" + currQuestionDataTable.Rows[0].ItemArray[5].ToString(), "Good Job"); numAnswersCorrectly++; } else { MessageBox.Show("Sorry! You are incorrect. \n\n" + currQuestionDataTable.Rows[0].ItemArray[5].ToString(), "Incorrect"); } goToNextQuestion(); } else { MessageBox.Show("You need to choose either true or false.", "Error"); } } private void validMatchAnswer() { //Populate correct LOA string tmpCol = currQuestionDataTable.Rows[0].ItemArray[3].ToString(); //Create Array that contains all values ArrayList alCol = new ArrayList(); 119 int i = 0; while (i < tmpCol.Length) { int tmpPlace = tmpCol.IndexOf(";;;", i); alCol.Add(tmpCol.Substring(i, tmpPlace - i)); i = tmpPlace + 3; } //Populate array with student entered LOA for comparison ArrayList alCol1 = new ArrayList(); if (!txtMatch2_1.Text.Equals("")) alCol1.Insert(0, txtMatch2_1.Text); if (!txtMatch2_2.Text.Equals("")) alCol1.Insert(1, txtMatch2_2.Text); if (!txtMatch2_3.Text.Equals("")) alCol1.Insert(2, txtMatch2_3.Text); if (!txtMatch2_4.Text.Equals("")) alCol1.Insert(3, txtMatch2_4.Text); if (!txtMatch2_5.Text.Equals("")) alCol1.Insert(4, txtMatch2_5.Text); if (!txtMatch2_6.Text.Equals("")) alCol1.Insert(5, txtMatch2_6.Text); if (!txtMatch2_7.Text.Equals("")) alCol1.Insert(6, txtMatch2_7.Text); if (!txtMatch2_8.Text.Equals("")) alCol1.Insert(7, txtMatch2_8.Text); if (!txtMatch2_9.Text.Equals("")) alCol1.Insert(8, txtMatch2_9.Text); if (!txtMatch2_10.Text.Equals("")) alCol1.Insert(9, txtMatch2_10.Text); if (alCol1.Count >= alCol.Count) { if (arrayCompare(alCol, alCol1)) { MessageBox.Show("Congratulations! You are correct!", "Good Job"); numAnswersCorrectly++; } else { string correctAnswer = "\n"; for (int s = 0; s < alCol.Count; s++) { correctAnswer += alCol[s].ToString() + "\n"; } MessageBox.Show("Sorry! You are incorrect. \n\nThe correct order is: " + correctAnswer, "Incorrect"); } goToNextQuestion(); } else { MessageBox.Show("Please enter values next to each column in column 1.", "Error"); } } private bool arrayCompare(ArrayList al1, ArrayList al2) 120 { bool areSame = true; if (al1.Count != al2.Count) { areSame = false; } else { for (int i = 0; i < al1.Count; i++) { if (!al1[i].ToString().ToUpper().Equals(al2[i].ToString().ToUpper())) { areSame = false; break; } } } return areSame; } private void goToNextQuestion() { if (currQuestionNum < numOfQuestions) { currQuestionNum++; setUpQuestion(); } else { MessageBox.Show("You have completed the quiz.\nYou have answered " + numAnswersCorrectly.ToString() + " out of " + numOfQuestions.ToString() + " questions correctly!", "Done"); this.Close(); } } private void cleanOutAnswer() { rbTrue.Checked = false; rbFalse.Checked = false; rbAnsA.Checked = false; rbAnsB.Checked = false; rbAnsC.Checked = false; rbAnsD.Checked = false; txtMatch2_1.Text = ""; txtMatch2_2.Text = ""; txtMatch2_3.Text = ""; txtMatch2_4.Text = ""; txtMatch2_5.Text = ""; txtMatch2_6.Text = ""; txtMatch2_7.Text = ""; txtMatch2_8.Text = ""; txtMatch2_9.Text = ""; txtMatch2_10.Text = ""; } 121 #endregion #region Events private void TakeQuiz_FormClosed(object sender, FormClosedEventArgs e) { Program.takeQuizOpen = false; } private void btnSubmitAnswer_Click(object sender, EventArgs e) { if ((currQuestionDataTable != null) && currQuestionDataTable.Rows.Count > 0) { string questType = currQuestionDataTable.Rows[0].ItemArray[4].ToString(); if (questType.Equals("MC")) { validMCAnswer(); } else if (questType.Equals("T/F")) { validTFAnswer(); } else { validMatchAnswer(); } cleanOutAnswer(); } } private void btnSkipQuestion_Click(object sender, EventArgs e) { cleanOutAnswer(); goToNextQuestion(); } #endregion } } /********************************************************************* * Author: Suzanne Minton * File: TitlePageCreation.cs * Date: 2008-2009 * Description: Page for creating the title page. *********************************************************************/ using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; 122 using System.Text; using System.Windows.Forms; namespace MasterProject { public partial class TitlePageCreation : Form { #region Variables private string mode = ""; #endregion #region Constructor public TitlePageCreation(string lessonTitle) { InitializeComponent(); this.Text = "Title Page Creation"; lblLessonName.Text = lessonTitle; populatePage(); Program.titlePageCreationOpen = true; } #endregion #region Methods private void populatePage() { dsCAITTableAdapters.TitlePageTableAdapter tpta = new MasterProject.dsCAITTableAdapters.TitlePageTableAdapter(); dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); int id = Convert.ToInt32(lta.GetLessonIdFromTitle(lblLessonName.Text)); try { dsCAIT.TitlePageDataTable tpdt = tpta.GetTitlePageInformation(id); if (tpdt.Rows.Count > 0) { rtxtSummary.Text = tpdt.Rows[0].ItemArray[1].ToString(); rtxtGoalsObjectives.Text = tpdt.Rows[0].ItemArray[2].ToString(); rtxtDirections.Text = tpdt.Rows[0].ItemArray[4].ToString(); mode = "Edit"; } else { mode = "Add"; } } catch (Exception ex) { MessageBox.Show("There was a problem getting the title page information from the database."); } } 123 #endregion #region Events private void btnCancel_Click(object sender, EventArgs e) { this.Close(); } private void btnSave_Click(object sender, EventArgs e) { dsCAITTableAdapters.TitlePageTableAdapter tpta = new MasterProject.dsCAITTableAdapters.TitlePageTableAdapter(); dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); try { int id = Convert.ToInt32(lta.GetLessonIdFromTitle(lblLessonName.Text)); if (mode.Equals("Add")) { tpta.InsertTitlePage(id, rtxtSummary.Text, rtxtGoalsObjectives.Text, rtxtDirections.Text); } else { tpta.UpdateTitlePage(rtxtSummary.Text, rtxtGoalsObjectives.Text, rtxtDirections.Text, id); } this.Close(); } catch (Exception ex) { MessageBox.Show("There was a problem saving the title page.", "Error"); } } private void TitlePageCreation_FormClosed(object sender, FormClosedEventArgs e) { Program.titlePageCreationOpen = false; } #endregion } } /********************************************************************* * Author: Suzanne Minton * File: ViewLesson.cs * Date: 2008-2009 * Description: Page for viewing lessons *********************************************************************/ using System; using System.Collections.Generic; using System.ComponentModel; 124 using using using using using using System.Data; System.Drawing; System.Text; System.Windows.Forms; System.IO; System.Diagnostics; namespace MasterProject { public partial class ViewLesson : Form { #region Declarations private int _lessonID; #endregion #region Constructor public ViewLesson(string lessonTitle, int LessonID) { InitializeComponent(); _lessonID = LessonID; lblTitle.Text = lessonTitle; populateGrid(); FileManager fm = new FileManager(); txtText.Text = fm.viewLesson(lessonTitle); Program.viewLessonOpen = true; } #endregion #region Methods private void populateGrid() { this.grdAttachments.DataSource = this.attachmentTableAdapter.GetAttachmentsByLessonID(_lessonID); } #endregion #region Events private void btnMainMenu_Click(object sender, EventArgs e) { this.Close(); } private void ViewLesson_FormClosed(object sender, FormClosedEventArgs e) { Program.viewLessonOpen = false; } private void btnOpenAttach_Click(object sender, EventArgs e) { if (grdAttachments.SelectedRows.Count > 0) { DataGridViewRow selectedRow = grdAttachments.SelectedRows[0]; int attachId = (int)selectedRow.Cells[0].Value; try { dsCAITTableAdapters.AttachmentTableAdapter ata = new MasterProject.dsCAITTableAdapters.AttachmentTableAdapter(); 125 DataTable dtAttachment = ata.GetAttachmentByAttachmentID(attachId); if (dtAttachment.Rows.Count == 1) { byte[] data = (byte[])dtAttachment.Rows[0]["Attachment"]; File.WriteAllBytes(@"C:\temp\lessons\" + dtAttachment.Rows[0]["linkname"], data); Process.Start(@"C:\temp\lessons\" + dtAttachment.Rows[0]["linkname"]); } } catch (Exception ex) { MessageBox.Show("There was a problem getting the attachment from the database."); } } } #endregion } } /********************************************************************* * Author: Suzanne Minton * File: ViewTitlePage.cs * Date: 2008-2009 * Description: Page for viewing title page *********************************************************************/ using using using using using using using System; System.Collections.Generic; System.ComponentModel; System.Data; System.Drawing; System.Text; System.Windows.Forms; namespace MasterProject { public partial class ViewTitlePage : Form { #region Constructor public ViewTitlePage(string lessonTitle) { InitializeComponent(); lblLessonName.Text = lessonTitle; populateTextBoxes(lessonTitle); Program.viewTitlePage = true; } #endregion #region Methods private void populateTextBoxes(string lessonTitle) 126 { dsCAITTableAdapters.TitlePageTableAdapter tpta = new MasterProject.dsCAITTableAdapters.TitlePageTableAdapter(); dsCAITTableAdapters.LessonTableAdapter lta = new MasterProject.dsCAITTableAdapters.LessonTableAdapter(); try { int id = Int32.Parse(lta.GetLessonIdFromTitle(lessonTitle).ToString()); dsCAIT.TitlePageDataTable tpdt = tpta.GetTitlePageInformation(id); if (tpdt.Rows.Count { txtSummary.Text txtGandO.Text = txtSpecDir.Text } > 0) = tpdt.Rows[0].ItemArray[1].ToString(); tpdt.Rows[0].ItemArray[2].ToString(); = tpdt.Rows[0].ItemArray[4].ToString(); } catch (Exception ex) { MessageBox.Show("There was a problem with the database."); } } #endregion #region Events private void btnClose_Click(object sender, EventArgs e) { this.Close(); } private void ViewTitlePage_FormClosed(object sender, FormClosedEventArgs e) { Program.viewTitlePage = false; } #endregion } } [10] 127 REFERENCES [1] R.L. Jamieson, Marchem: A Guide for Developing Computer Assisted Instructional Tutorials, Thesis for Master of Arts in Education (Curriculum and Instruction) at California State University, Sacramento, Spring 1987. [2] Microsoft. (2009). Microsoft Download Center. Microsoft Corporation. [Online]. Available: http://www.microsoft.com/downloads [3] M.A. Lorber. (2008, July). Computers as Instructional Aids. Illinois State College of Education, IL. [Online]. Available: people.coe.ilstu.edu [4] Merlot. (1997). MERLOT Multimedia Educational Resource for Learning and Online Teaching. California State University, Long Beach. [Online]. Available: http://www.merlot.org/merlot/index.htm [5] Wikipedia, The Free Encyclopedia. (2009, Oct.). Moodle. Wikimedia Foundation, Inc. [Online]. Available: http://en.wikipedia.org/wiki/moodle [6] Wikipedia, The Free Encyclopedia. (2009, Oct.). WebCT. Wikimedia Foundation, Inc. [Online]. Available: http://en.wikipedia.org/wiki/webct [7] D. Howe. (2002, Jan.). FOLDOC Free On-Line Dictionary Of Computing. Imperial College Department of Computing. [Online]. Available: http://foldoc.org/ [8] Wikipedia, The Free Encyclopedia. (2009, Oct.). Use Case Diagram. Wikimedia Foundation, Inc. [Online]. Available: http://en.wikipedia.org/wiki/Use_case_diagram [9] T.C. Lethbridge. (2003, Apr.). Fact Guru Object Oriented Software Engineering Knowledge Base. Fact Guru, Ontario, Canada. [Online]. Available: http://www.csi.uottawa.ca:4321/oose/index.html [10] K.Watson, C. Nagel, J.H. Pedersen, J.D. Reid, M. Skinner, E. White, Beginning Visual C# 2005. Indianapolis, IN: Wiley Publishing, Inc., 2006, pp 3-321, 391574, 771-847.