These are just notes from my self-studies…mostly for my own reference, but maybe you’ll find something useful here.
2015
Classes and Constructors C# DB Date and Time Create Method Arrays Collections LINQ Enumeration and Switch Handling Exceptions Events Inheritance Interfaces
Remove Dupes from list
using System; using System.Collections.Generic; using System.Linq; class Program { static void Main() { // List with duplicate elements. List<int> list = new List<int>(); list.Add(1); list.Add(2); list.Add(3); list.Add(3); list.Add(4); list.Add(4); list.Add(4); foreach (int value in list) { Console.WriteLine("Before: {0}", value); } // Get distinct elements and convert into a list again. List<int> distinct = list.Distinct().ToList(); foreach (int value in distinct) { Console.WriteLine("After: {0}", value); } } }
using System; using System.Collections.Generic; class Program { static void Main() { HashSet<int> evenNumbers = new HashSet<int>(); HashSet<int> oddNumbers = new HashSet<int>(); for (int i = 0; i < 5; i++) { // Populate numbers with just even numbers. evenNumbers.Add(i * 2); // Populate oddNumbers with just odd numbers. oddNumbers.Add((i * 2) + 1); } Console.Write("evenNumbers contains {0} elements: ", evenNumbers.Count); DisplaySet(evenNumbers); Console.Write("oddNumbers contains {0} elements: ", oddNumbers.Count); DisplaySet(oddNumbers); // Create a new HashSet populated with even numbers. HashSet<int> numbers = new HashSet<int>(evenNumbers); Console.WriteLine("numbers UnionWith oddNumbers..."); numbers.UnionWith(oddNumbers); Console.Write("numbers contains {0} elements: ", numbers.Count); DisplaySet(numbers); } private static void DisplaySet(HashSet<int> set) { Console.Write("{"); foreach (int i in set) { Console.Write(" {0}", i); } Console.WriteLine(" }"); } } /* This example produces output similar to the following: * evenNumbers contains 5 elements: { 0 2 4 6 8 } * oddNumbers contains 5 elements: { 1 3 5 7 9 } * numbers UnionWith oddNumbers... * numbers contains 10 elements: { 0 2 4 6 8 1 3 5 7 9 } */
Or
public static List<PointF> RemoveDuplicates(List<PointF> listPoints) { List<PointF> result = new List<PointF>(); for (int i = 0; i < listPoints.Count; i++) { if (!result.Contains(listPoints[i])) result.Add(listPoints[i]); } return result; }
Learning material from Programming in C# Jump Start
01 | Object Oriented Programming, Managed Languages and C#
02 | Constructing Complex Types- Object Interfaces and Inheritance
03 | Code Reflection and Information- Working with Garbage Collection
04 | Controlling Programmatic Flow- Manipulating Types and Strings
05 | Advanced C#, Type and Value Validation- Encryption Techniques
06 | Splitting Assemblies and WinMD- Diagnostics and Instrumentation
07 | Interacting with the File System- Leveraging Web Services
08 | Using LINQ to Objects and XML- Fundamentals of Serialization
Learning material from A Guide to Object Oriented Practices
00 | Introduction
01 | Encapsulation
02 | Inheritance
03 | Interfaces
04 | Abstract Classes
05 | Generics
06 | Delegates, Events, and Lambda Expressions
07 | Functional Concepts
Notes from the lesson on Interfaces:
An Interface defines a contract that can be implemented by many unrelated classes.
The interfaces provide a way to define behavior that can be implemented by unrelated types.
There are important differences between classes and interfaces:
-Interfaces cannot contain any implementation. They only define the contract.
-A class can implement multiple interfaces. It can only have one direct base class.
These differences mean important implications for their use.
Advantages of Interfaces
-Contract Definition
-Polymorphism among unrelated types
-Treat unrelated types similarly
Polymorphism means that we can write functionality using the base class references. This means algorithms can be shared by writing the methods using only the base class methods and properties.
Language Support for Interfaces
-Interfaces may be public, or internal
-Interfaces may extend other interfaces
-Classes can implement multiple interfaces
. Must implement all members
. Or be abstract (more later)
-May implement interfaces implicitly or explicitly.
Liskov Substitutability Principle applies to interfaces as well
Keep Contracts Small
-SRP is critically important for interface definitions
. The smaller and more focused the better
-Each interface should represent a single “feature” or “task”
. When you have related interfaces, consider inheritance
. Carefully!
. Larger contracts can often result in contracts that are “almost” completely implemented.
. Methods that are implemented with a MethodNotImplementedException are a bad code small.
. Larger contracts make it harder to satisfy Liskov.
. Larger contracts often involve leaky abstractions.
Avoid Marker Interfaces
-A Marker interface is an interface with no members.
-They can be used to ‘mark’ capabilities.
-Require Reflection to find instances
Practice: Common Abstraction
-Interfaces provide contracts for functionality
-Can be implemented by completely unrelated types
. Example: Enumerating a sequence
. Container
. Characters in a String
. Lines in a file
Practice: Interfaces for Client code
-You can specify required contracts for contract code
. Create interfaces clients must implement
-Algorithms can be open for extension
Practice: Interfaces for Client code
-You can specify required contracts for contract code
. Create interfaces clients must implement
-Algorithms can be open for extension
Practice: Interfaces for Test Doubles
-Test Doubles (in static languages) must have a type
-That type must be a substitute for the production type
. That often implies an interface that can be mocked.
-Necessary, but often not part of the application design
Good Outcome: Natural Implementation
-Implementing an interface should be “natural”
-Implementing an interface should be “obvious”
-Corollary:
.Implementations for interfaces should be complete
Good Outcome: Complete Implementation
-Interface Implementers can create Complete Implementations
-Never see NotImplementedException
Risk: Copied implementation
-This is often caused by:
.Contracts with too many requirements
.Convenience Methods in Interfaces
-“All in one” interface
The larger and more complicated interfaces are, the fewer classes implement all of those members in an obvious manner.
Notes from today’s lesson on Inheritance:
Inheritance is the technique of reusing code by creating base classes for behavior that is shared by multiple derived classes that implement specializations of the base class.
Inheritance is one of the most common OO idioms to achieve reuse in your designs. It’s a very powerful idiom. It’s also one that if you overuse, it can cause lots of problems.
Advantages of Inheritance
-Implementation Reuse
-Shared base class implementation for all derived classes
-Polymorphism Support
Language Support for Inheritance
Classes can declare a single base class
-Derived Classes inherit all base class functionality
Can call protected members in the base class
-Can access protected fields in the base class
Virtual Members
-Can be re-implemented by derived classes
-Can be abstract (which we will discuss later)
Start with Leaf Classes
Begin by Defining Classes For your Application
-Don’t Focus on Inheritance too early
Look for common behavior as you add classes
-Remember the “is a” catchphrase
It’s hard to design base classes until you see some of the derived classes
It’s much easier to see inheritance opportunities when you see some leaf classes.
Search for Common Behavior
-Common Behavior represents base class implementation
-Common Storage may not be important
The most important benefits from inheritance come from sharing implementation of behavior, not common storage.
Common storage doesn’t really save much in terms of code or space.
Also, common storage may not represent the kind of behavior that we want to get from implementation reuse. It may be just a coincidence.
Liskov Substitutability Principle
All the time we design a program module and we create some class hierarchies. Then we extend some classes creating some derived classes.
We must make sure that the new derived classes just extend without replacing the functionality of old classes. Otherwise the new classes can produce undesired effects when they are used in existing program modules.
Likov’s Substitution Principle states that if a program module is using a Base class, then the reference to the Base class can be replaced with a Derived class without affecting the functionality of the program module.
Practice: Consider Inheritance over Copy/Paste
I need something like
-Separate common parts into base
-Create 2 derived classes
Practice: Leverage the .NET Base Class Library
-There’s a lot of functionality you can reuse
-Classes (usually) designed for use as base classes
-Tested implementations for common patterns
There are a lot of classes in the .NET BCL that are designed to be used as base classes. Use them. You’ll learn how to create derived classes, how to use and extend base classes.
Practice: Seek Common Behavior
Can seemingly unrelated classes share implementation?
-Sometimes, if the behavior is shared.
Example
-Memory Stream
-File Stream
-String Stream
Good Outcome: Generalities in Base classes
-Behavior that can be shared is shared
-Codebase is smaller
-New Derived classes can be developed quickly
Good Outcome: Polymorphism that works
-New derived classes can be used in existing scenarios
-Follow Liskov Substitutability Principle
Derived class are immediately useful. They can be used in all places where the base class can already be used. Polymorphism makes it easier to incorporate new derived classes very quickly.
Risk: “Almost is-a”
-This is an example of a leaky abstraction
-Look for Violations of the Liskov Substitutability Principle
Risk: Too Deep Hierarchy
-Very Deep hierarchies make it hard to discover functionality
-Increases the chances of LSP violations
-Increasing limiting to extensions
. Derived classes inherit too much functionality
Risks: Downcasting needed
-Downcasting is converting a base class to a derived class
-Another example of an LSP violation
. You need to get at the base class functionality
-Example of a leaky abstraction
Notes from today’s lesson on Encapsulation
Advantages of Encapsulation
-Fewer name collisions
-Refactoring code is easier
-Smaller API Footprint
-Elements with less visibility can be changed more safely
Language Support for Encapsulation
Classes:
-Public
-Internal
-Private
Members:
-Public
-Internal
-Protected Internal
-Private (default)
The C# language (and VB.NET) provide a rich vocabulary to specify the accessibility of each element.
Note that the default accessibility is limited. That’s to encourage you to create elements with less visibility. (but it’s a good idea to be explicit for readability)
Good rule of thumb is to start limited and slowly expose as you need it.
Strive for small classes
‘Small’ is a relative term
-Avoid Feature Creep
-Minimize the public API
Avoid any Unnecessary Additions
-Consider More classes
-Avoid extra convenience methods
Classes should be focused.
API Surface area should be as small and focused as possible.
API should focus on what, and hide all the how for the algorithm.
Single Responsibility Principle
A class should be responsible for exactly one item of functionality
-Related to Separation of Concerns
-The ‘S’ in the SOLID Principles
Classes with exactly one responsibility are easier to enforce encapsulation.
The focus minimizes the need for increased visibility.
SOLID (Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion).
Practice: Public Methods are Minimized
-Fewer public methods means minimal surface area
-Minimal Surface Area means opportunities for encapsulation
The key discussion item is that we want to minimize the “what”, so that we can keep the “how” private.
Practice: All Member Fields are Private
Advantages:
-Gated access through properties
-Validation on any updates or modifications
-Storage model can change without affecting client code.
Concerns:
-Can provide layers of latency without value.
Practice: Properties Provide Validation
Advantages:
-An object can be guaranteed to be in a valid state
-Invalid transformations are blocked
-Private methods can assume a valid state
If an object is always in a valid state, then private methods can simply do their work.
They need less error checking, because private methods can assume that an object is valid.
Practice: Public Accessors Provide Safe Access
-Can return computed data
-Can return interface reference
. Instead of direct access
-Can return a transformation
Hiding direct access means hiding ‘how’
Practice: Public Mutators Require Validation
-“Gated” API for any changes
-Ensures Validity
. Throw exception on invalid transformations
-Keep Object state consistent
This protects object invariants
Objects are valid
Private, encapsulated items are hidden.
Practice: Mutators Complete or Do Nothing
-Keeps Valid Objects Valid
-State is always known
-Either all changes are made
-or-
-None of the changes are made
Today, I learned about Handling Exceptions and working with Events.
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace HandlingExceptions { class Program { static void Main(string[] args) { // Test to make sure the text file works string content1 = File.ReadAllText(@"C:\_CSharp\TextFile.txt"); MessageBox.Show(content1, "Contents of File"); // output: "Success usually comes to those who are too busy to be looking for it." Henry David Thoreau // Test for an error now ////string content2 = File.ReadAllText(@"C:\_CSharp\TextFileError.txt"); ////MessageBox.Show(content2, "Contents of File"); // output: An unhandled exception of type 'System.IO.FileNotFoundException' occurred in mscorlib.dll // Additional information: Could not find file 'C:\_CSharp\TextFileError.txt'. // To prevent this error from appearing, you add a Try Catch try { string content2 = File.ReadAllText(@"C:\_CSharp\TextFileError.txt"); MessageBox.Show(content2, "Contents of File"); } catch { MessageBox.Show("The catch caught the error.", "Catch"); } // Now, you get the first pop up fine, and the second one (the error) isn't shown. // The catch handles the error. // Sometimes, you'll want to catch the exception error and display it // or do something else with it. try { string content2 = File.ReadAllText(@"C:\_CSharp\TextFileError.txt"); MessageBox.Show(content2, "Contents of File"); } catch (Exception ex) { MessageBox.Show(ex.Message.ToString(), "Display Error"); MessageBox.Show("Or, display...There was a problem.", "Display Custom Message"); } // Now, to extend the power of the try/catch, you can look for specfic exceptions // and then do things based upon the catch error try { string content2 = File.ReadAllText(@"C:\_CSharp\TextFileError.txt"); MessageBox.Show(content2, "Contents of File"); } // catch for the file catch (FileNotFoundException) { MessageBox.Show("Missing File! Please verify the file name is TextFile.txt", "File Error"); } // catch for the directory catch (DirectoryNotFoundException) { MessageBox.Show(@"Missing Directory! Please verify the file is in the C:\_CSharp folder", "Directory Error"); } // catch general catch for everything else catch (Exception ex) { MessageBox.Show(ex.Message.ToString(), "Display Error"); } // there is also the FINALLY statement // this code runs no matter what // code to finalize // settings objects top null // closing database connections finally { MessageBox.Show("Closing Application.", "Finally"); } } } }
Working with Events
You can attach multiple event handlers to an event raised by a class using the following syntax:
myClass.MyEvent += myEventHandler;
using System; using System.Threading.Tasks; using System.Timers; using System.Windows.Forms; namespace TimerExample { class Program { static void Main(string[] args) { System.Timers.Timer myTimer = new System.Timers.Timer(2000); // ties the timer to the specified events MyTimer_Elapsed1 and MyTimer_Elapsed2 myTimer.Elapsed += MyTimer_Elapsed1; myTimer.Elapsed += MyTimer_Elapsed2; // starts the timer myTimer.Start(); // this segment will remove the red Console.WriteLine("Press enter to remove the red event."); Console.ReadLine(); myTimer.Elapsed -= MyTimer_Elapsed1; Console.ReadLine(); } private static void MyTimer_Elapsed1(object sender, ElapsedEventArgs e) { // default statement // throw new NotImplementedException(); // will display the time in the console Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Elapsed time #1: {0:HH:mm:ss.fff}", e.SignalTime); // or this works in a dialog box //MessageBox.Show("Elapsed time #1: " + e.SignalTime.ToLongTimeString()); } private static void MyTimer_Elapsed2(object sender, ElapsedEventArgs e) { // will display the time in the console Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Elapsed time #2: {0:HH:mm:ss.fff}", e.SignalTime); // or this works in a dialog box //MessageBox.Show("Elapsed time: #2: " + e.SignalTime.ToLongTimeString()); } } }
New Project: WPF with Events
MainWindow.xaml.cs
using System; using System.Windows; namespace WpfApplication2 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); button.Click += buttonMyOtherClick; } private void buttonMyOtherClick(object sender, RoutedEventArgs e) { myOtherLabel.Content = "I created this second event!"; } private void button_Click(object sender, RoutedEventArgs e) { myLabel.Content = "Hello world!"; } } }
MainWindow.xaml
<Window x:Class="WpfApplication2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication2" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <Button x:Name="button" Content="Click Me" HorizontalAlignment="Left" Margin="69,67,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/> <Label x:Name="myLabel" Content="" HorizontalAlignment="Left" Margin="204,67,0,0" VerticalAlignment="Top"/> <Label x:Name="myOtherLabel" Content="" HorizontalAlignment="Left" Margin="221,177,0,0" VerticalAlignment="Top"/> </Grid> </Window>
Today, I learned about Enumerations and the Switch decision statement.
using System; using System.Collections.Generic; using System.Windows.Forms; namespace EnumAndSwitch { class Program { static void Main(string[] args) { List<Todo> todos = new List<Todo>() { new Todo { Description = "Task1", EstimatedHours = 6, Status = Status.Completed }, new Todo { Description = "Task2", EstimatedHours = 2, Status = Status.InProgress }, new Todo { Description = "Task3", EstimatedHours = 8, Status = Status.NotStarted }, new Todo { Description = "Task4", EstimatedHours = 12, Status = Status.Deleted }, new Todo { Description = "Task5", EstimatedHours = 6, Status = Status.InProgress }, new Todo { Description = "Task6", EstimatedHours = 2, Status = Status.NotStarted }, new Todo { Description = "Task7", EstimatedHours = 14, Status = Status.Completed }, new Todo { Description = "Task8", EstimatedHours = 8, Status = Status.Completed }, new Todo { Description = "Task9", EstimatedHours = 8, Status = Status.Completed }, new Todo { Description = "Task10", EstimatedHours = 8, Status = Status.Completed }, new Todo { Description = "Task11", EstimatedHours = 4, Status = Status.NotStarted }, new Todo { Description = "Task12", EstimatedHours = 10, Status = Status.Completed }, new Todo { Description = "Task13", EstimatedHours = 12, Status = Status.Deleted }, new Todo { Description = "Task14", EstimatedHours = 6, Status = Status.Completed } }; PrintAssessment(todos); Console.ReadLine(); } private static void PrintAssessment(List<Todo> todos) { foreach (var todo in todos) { switch (todo.Status) { case Status.NotStarted: //some operation //MessageBox.Show("Status is NotStarted!", todo.Description); break; case Status.InProgress: //some operation //MessageBox.Show("Status is InProgress!", todo.Description); break; case Status.OnHold: //some operation //MessageBox.Show("Status is OnHold!", todo.Description); break; case Status.Completed: //some operation //MessageBox.Show("Status is Completed!", todo.Description); break; case Status.Deleted: //some operation //MessageBox.Show("Status is Deleted!", todo.Description); break; default: break; } MessageBox.Show(todo.Status.ToString(), todo.Description); } } } class Todo { public string Description { get; set; } public int EstimatedHours { get; set; } public Status Status { get; set; } } enum Status { NotStarted, InProgress, OnHold, Completed, Deleted } }
Today, I explored Structured Query Language and the LINQ syntax.
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using System.Text; using System.Threading.Tasks; namespace UnderstandingLINQ { class Program { static void Main(string[] args) { string output1 = string.Empty; string output2 = string.Empty; string output3 = string.Empty; string output4 = string.Empty; string output5 = string.Empty; string output6 = string.Empty; List<Car> myCars = new List<Car>() { new Car() { VIN="A1-00-001", Make = "BMW", Model = "550i", StickerPrice = 55000, Year = 2009 }, new Car() { VIN="B1-00-002", Make = "Toyota", Model = "4Runner", StickerPrice = 35000, Year = 2010 }, new Car() { VIN="C1-00-003", Make = "BMW", Model = "745li", StickerPrice = 75000, Year = 2008 }, new Car() { VIN="D1-00-004", Make = "Ford", Model = "Escape", StickerPrice = 25000, Year = 2008 }, new Car() { VIN="E1-00-005", Make = "BMW", Model = "55i", StickerPrice = 57000, Year = 2010 } }; // LINQ Query var bmws1 = from car in myCars where car.Make == "BMW" select car; var bmws2 = from car in myCars where car.Make == "BMW" & car.Year == 2010 select car; // example of projection, anonymous types var newCars = from car in myCars where car.Make == "BMW" & car.Year == 2010 select new { car.Make, car.Model }; // LINQ method - uses lambdas expressions (mini methods) // reference lambdas: https://msdn.microsoft.com/en-us/library/bb397687.aspx var bmws3 = myCars.Where(p => p.Make == "BMW"); var bmws4 = myCars.Where(p => p.Make == "BMW" & p.Year == 2010); // LINQ Query 1 foreach (var car in bmws1) { // Concatenate items in list output1 = string.Join("\n", bmws1.Select(i => i.Model + " " + i.VIN).ToArray()); } MessageBox.Show("LINQ Query 1: \n\n" + output1); // LINQ Query 2 foreach (var car in bmws2) { // Concatenate items in list output2 = string.Join("\n", bmws2.Select(i => i.Model + " " + i.VIN).ToArray()); } MessageBox.Show("LINQ Query 2: \n\n" + output2); // LINQ Method 1 foreach (var car in bmws3) { // Concatenate items in list output3 = string.Join("\n", bmws3.Select(i => i.Model + " " + i.VIN).ToArray()); } MessageBox.Show("LINQ Method 1: \n\n" + output3); // LINQ Method 2 foreach (var car in bmws4) { // Concatenate items in list output4 = string.Join("\n", bmws4.Select(i => i.Model + " " + i.VIN).ToArray()); } MessageBox.Show("LINQ Method 2: \n\n" + output4); // LINQ Query Syntax Returned an ordered list var orderedCars1 = from car in myCars orderby car.Year descending select car; foreach (var car in orderedCars1) { // Concatenate items in list output5 = string.Join("\n", orderedCars1.Select(i => i.Year + " " + i.Model).ToArray()); } MessageBox.Show("Ordered list: \n\n" + output5, "LINQ Query"); // LINQ Method Syntax Returned an ordered list var orderedCars2 = myCars.OrderByDescending(p => p.Year); foreach (var car in orderedCars2) { // Concatenate items in list output6 = string.Join("\n", orderedCars2.Select(i => i.Year + " " + i.Model).ToArray()); } MessageBox.Show("Ordered list: \n\n" + output6, "LINQ Method"); // LINQ Method Find first item var firstBMW1 = myCars.First(p => p.Make == "BMW"); MessageBox.Show("The first BMW is: " + firstBMW1.VIN, "Ascending"); var firstBMW2 = myCars.OrderByDescending(p => p.Year).First(p => p.Make == "BMW"); MessageBox.Show("The first BMW is: " + firstBMW2.VIN, "Descending"); // Directly in output MessageBox.Show("Greater than 2012? " + myCars.TrueForAll(p => p.Year > 2012).ToString(),"Bool Value"); MessageBox.Show("Greater than 2009? " + myCars.TrueForAll(p => p.Year > 2009).ToString(), "Bool Value"); MessageBox.Show("Greater than 2005? " + myCars.TrueForAll(p => p.Year > 2005).ToString(), "Bool Value"); // Step through using ForEach myCars.ForEach(p => MessageBox.Show(string.Format("ForEach: {0} {1:C}", p.VIN, p.StickerPrice), "Less Code")); // Perform an operation on the data myCars.ForEach(p => p.StickerPrice -= 3000); myCars.ForEach(p => MessageBox.Show(string.Format("ForEach: {0} {1:C}", p.VIN, p.StickerPrice), "Subtract $3,000")); // Check to see if car exists in our list MessageBox.Show("Does the car exist? " + myCars.Exists(p => p.Model == "745li").ToString(), "Exists"); // Show total value of all our cars MessageBox.Show(string.Format("What is the total value of our cars? {0:C}", myCars.Sum(p => p.StickerPrice)), "Total Value"); // Show the type of the object MessageBox.Show("What is the type of the car object? \n\n" + myCars.GetType().ToString(), "Object Type"); // Compare to other object string testType1 = myCars.GetType().ToString(); string testType2 = orderedCars1.GetType().ToString(); MessageBox.Show(string.Format("Car Object\n{0}\n\n" + "Ordered Car\n{1}", testType1, testType2), "Compare Types"); string testType3 = bmws1.GetType().ToString(); MessageBox.Show("What is the bmws type?\n\n" + testType3, "Where Type"); // Demo of projection - data type string testType4 = newCars.GetType().ToString(); MessageBox.Show("What is the newCars type?\n\n " + testType4, "Anonymous Type"); } class Car { public string VIN { get; set; } public string Make { get; set; } public string Model { get; set; } public int Year { get; set; } public double StickerPrice { get; set; } } } }
Collections
Today’s lesson was about Collections, the older type, the new type, and how to use them. I’ve added more commenting and pop up message boxes that were not a part of the lesson, but make the material easier to understand.
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WorkingWithCollections { class Program { static void Main(string[] args) { Car car1 = new Car(); car1.Make = "Oldsmobile"; car1.Model = "Cutlas Supreme"; car1.VIN = "A1"; Car car2 = new Car(); car2.Make = "Geo"; car2.Model = "Prism"; car2.VIN = "B1"; Book b1 = new Book(); b1.Author = "Eddie Jackson"; b1.Title = "Microsoft Computer Automation"; b1.ISBN = "1-234-12345-3"; /* older style of collections // ArrayLists are dynamically sized, // supports sorting, remove items ArrayList myArrayList = new ArrayList(); myArrayList.Add(car1); myArrayList.Add(car2); // demonstrating concept of cast/exception error //allows you to add book to the list myArrayList.Add(b1); myArrayList.Remove(b1); foreach (Car car in myArrayList) { Console.WriteLine(car.Make); } */ // Most popular collection // Newer style of collections // List<T> List<Car> myList = new List<Car>(); myList.Add(car1); myList.Add(car2); //now, when you try adding book to the list, it fails immediately //myList.Add(b1); foreach (Car car in myList) { // output MessageBox.Show(String.Format("The car from the foreach is: {0}", car.Model)); //Console.WriteLine(car.Model); } // Dictionary - Dictionary<TKey, TValue> Dictionary<string, Car> myDictionary = new Dictionary<string, Car>(); myDictionary.Add(car1.VIN, car1); myDictionary.Add(car2.VIN, car2); // output // return specific element in the array MessageBox.Show("The specified returned car is " + myDictionary["B1"].Make); //Console.WriteLine("The specified returned car is " + myDictionary["B1"].Make)); // Initialize an array with values string[] names = { "Eddie", "Jack", "Dan", "Terry" }; string output = string.Join("\n\n", names); //the \n means carriage return // output MessageBox.Show("Buyer Names\n\n" + output); //Console.WriteLine("Buyer Names\n\n" + output); // You can also initialize objects with values // no need for a Constructor here Car car3 = new Car() { Make = "BMW", Model = "750li", VIN = "C1" }; string output1 = string.Join("\n\n", car3.Make, car3.Model, car3.VIN); // output MessageBox.Show("New Car: " + output1); //Console.WriteLine("New Car: " + output1); Car car4 = new Car() { Make = "Ford", Model = "Taurus", VIN = "D1" }; string output2 = string.Join("\n\n", car4.Make, car4.Model, car4.VIN); // output MessageBox.Show("New Car: " + output2); //Console.WriteLine("New Car: " + output2); // Collection initializer // create a collection, added two objects, and intialize them List<Car> myList2 = new List<Car>() { new Car { Make = "Oldsmobile", Model = "Cutlass Supreme", VIN = "E1"}, new Car { Make = "Nissan", Model = "Altima", VIN = "F1" } }; foreach (Car car in myList2) { // output MessageBox.Show(String.Format("The car VIN from the foreach is: {0}", car.VIN)); //Console.WriteLine(car.VIN); } Console.WriteLine("Press the Enter key"); Console.ReadLine(); } } class Car { public string VIN { get; set; } public string Make { get; set; } public string Model { get; set; } } class Book { public string Title { get; set; } public string Author { get; set; } public string ISBN { get; set; } } }
The Class (a simple webpage scraper)
using System.IO; using System.Net; namespace MyCodeLibrary { public class Scrape { public string ScrapeWebpage(string url) { return GetWebpage(url); } public string ScrapeWebpage(string url, string filepath) { string reply = GetWebpage(url); File.WriteAllText(filepath, reply); return reply; } private string GetWebpage(string url) { WebClient client = new WebClient(); return client.DownloadString(url); } } }
Accessing the class
using MyCodeLibrary; using System; namespace MyClient { class Program { static void Main(string[] args) { Scrape myScrape = new Scrape(); string value = myScrape.ScrapeWebpage("http://msdn.microsoft.com/"); Console.WriteLine(value); Console.ReadLine(); } } }
Reference Assemblies
Today’s lesson was about creating and adding References to Assemblies. The video covered .NET assemblies: code libraries and executables, debug and release versions of assemblies. Plus, how to reference assemblies, utilize NuGet, and create references to custom libraries.
using System; using System.IO; using System.Net; namespace ConsoleApplication11 { class Program { static void Main(string[] args) { //write to file //string text = "This is to be written to a text file"; //File.WriteAllText(@"C:\CSharp\TextFile.txt", text); //by using site:microsoft.com, you can find classes and methods WebClient client = new WebClient(); string reply = client.DownloadString("http://msdn.microsoft.com"); //download and write to file (scraping) Console.WriteLine(reply); File.WriteAllText(@"C:\_CSharp\TextFile.txt", reply); Console.ReadLine(); } } }
Scope and Accessibility Modifiers
Today’s lesson was about understanding scope and accessibility modifiers as it applies to classes and methods.
using System; namespace ConsoleApplication10 { class Program { private static string k = ""; static void Main(string[] args) { string j = ""; for (int i = 0; i < 10; i++) { j = i.ToString(); k = i.ToString(); Console.WriteLine(i); if (i == 9) { string l = i.ToString(); } //Console.WriteLine(l); } //Console.WriteLine(i); Console.WriteLine("Outside of the for j: " + j); Console.WriteLine("Outside of the for k: " + k); HelperMethod(); Car myCar = new Car(); myCar.DoSomething(); Console.ReadLine(); } static void HelperMethod() { Console.WriteLine("Value of k from the HelperMethod(): " + k); } } class Car { public void DoSomething() { Console.WriteLine(helperMethod()); } private string helperMethod() { return "Hello world!"; } } }
CRUD – Database
I’ve been working on this the last day or so. It’s a small project that demonstrates C#, forms, and connecting to a database. The idea was to create something that I could store my friend’s phone numbers in — to be able to search, add, delete, and update records (commonly referred to as CRUD). It’s probably 95% done…I just need to add some error handling. The project that will follow this one will be a BitLocker database (to retrieve and store BitLocker passwords automatically).
— last updated 12/20/2015 —
The Form (in Visual Studio)
The app when launched
Form1.cs Code
using System; using System.Windows.Forms; using System.Data.OleDb; using System.Text.RegularExpressions; using System.Linq; using System.Data; namespace WindowsFormsApplication13 { public partial class Form1 : Form { //instantiate db connection public OleDbConnection DbConnection; public OleDbCommand cmd; public OleDbDataReader dr; public OleDbDataAdapter da; public DataSet ds; public DataTable dt; //global variables public string RecordValue; public string strGlobalName; public Form1() { InitializeComponent(); dataGridView1.AutoGenerateColumns = false; dataGridView1.AllowUserToAddRows = false; dataGridView1.ReadOnly = true; FormClosing += Form1_FormClosing; panel1.Enabled = false; panel2.Enabled = false; } private void Form1_Load(object sender, EventArgs e) { //fully populate/show all records //this.friendsTableAdapter.Fill(this.friendsDataSet.Friends); } //OPEN DBCONNECTION public void OpenDBConnection() { DbConnection = new OleDbConnection(Program.cnstr); DbConnection.ConnectionString = Program.cnstr; DbConnection.Open(); } //CLEAR FIELDS public void ClearFields() { txtSearch.Clear(); txtName.Clear(); txtPhone.Clear(); } //SET DATAGRIDVIEW public void SetDataGridView() { dataGridView1.RowHeadersVisible = false; dataGridView1.Columns[0].Width = 25; dataGridView1.Columns[1].Width = 200; dataGridView1.Columns[2].Width = 120; } //CHECK NAME public static Boolean isOnlyAlpha(string strToCheck) { Regex rg = new Regex("[^a-zA-Z]"); //if string has alpha only, return true return rg.IsMatch(strToCheck) == false ? true : false; } public void MessageValidName() { MessageBox.Show("Please enter a valid name here (no spaces, commas, or numbers)."); } //CHECK PHONE NUMBER public static Boolean isOnlyPhone(string numToCheck) { Regex rg = new Regex(@"\(?\d{3}\)?-? *\d{3}-? *-?\d{4}"); //if num matches a phone number, return true return rg.IsMatch(numToCheck) == false ? true : false; } public void MessageValidPhone() { MessageBox.Show("Please enter a valid phone number. <strong>Example</strong> 123-123-1234"); } //INTEGRITY CHECK, single method to check both Name and Phone //useful for Update, Delete, New private bool IntegrityCheck() { //jump to validate name if (isOnlyAlpha(txtName.Text) != true) { MessageValidName(); return false; } //jump to validate number if (isOnlyPhone(txtPhone.Text) == true) { MessageValidPhone(); return false; } return true; } //SEARCH DATABASE public void btnSearch_Click(object sender, EventArgs e) { if (txtSearch.Text == "") { MessageBox.Show("The search field cannot be empty."); return; } else { //calls the search field validation if (isOnlyAlpha(txtSearch.Text) == false) { //numbers have been detected MessageValidName(); ClearFields(); } else { panel1.Enabled = true; panel2.Enabled = false; panel3.Enabled = true; dataGridView1.Columns.Clear(); //open dbconnection OpenDBConnection(); string CommandText = @"SELECT * FROM Friends WHERE Name = " + "'" + txtSearch.Text + "'"; cmd = new OleDbCommand(CommandText, DbConnection); cmd.ExecuteNonQuery(); //check to see if a record exists based upon returned ID number int userCount = Convert.ToInt32(cmd.ExecuteScalar()); if (userCount == 0) { ClearFields(); panel1.Enabled = false; MessageBox.Show("Record does not exist!"); return; } dr = cmd.ExecuteReader(CommandBehavior.CloseConnection); int columnCount = 3; dataGridView1.ColumnCount = columnCount; string[] rowData = new string[columnCount]; while (dr.Read()) { dataGridView1.Columns[0].Name = "ID"; dataGridView1.Columns[1].Name = "Name"; dataGridView1.Columns[2].Name = "Phone"; rowData[0] = dr.GetInt32(0).ToString(); RecordValue = rowData[0]; rowData[1] = dr.GetString(1).ToString(); txtName.Text = rowData[1]; rowData[2] = dr.GetString(2).ToString(); txtPhone.Text = rowData[2]; //datagrid config SetDataGridView(); //add row data dataGridView1.Rows.Add(rowData); //set focus back to search txtSearch.Focus(); //clear fields ClearFields(); panel1.Enabled = false; } } } } //SAVE RECORD private void btnSave_Click(object sender, EventArgs e) { //check to make sure fields have data //call the integrity checker while (IntegrityCheck() == false) { return; } //open db connection OpenDBConnection(); string CommandText = "Insert into Friends(Name,Phone)Values('" + txtName.Text + "','" + txtPhone.Text + "')"; cmd = new OleDbCommand(CommandText, DbConnection); cmd.ExecuteNonQuery(); MessageBox.Show(txtName.Text + " was added!"); panel3.Enabled = true; panel2.Enabled = false; panel1.Enabled = false; strGlobalName = txtName.Text; ClearFields(); UpdateDatagridview(); } //DELETE RECORD public void btnDelete_Click(object sender, EventArgs e) { //call the integrity checker while (IntegrityCheck() == false) { return; } DialogResult result = MessageBox.Show("Are you sure you want to delete " + txtName.Text + "?", "Confirmation", MessageBoxButtons.YesNoCancel); if (result == DialogResult.Yes) { int RV = Convert.ToInt32(RecordValue); //open db connection OpenDBConnection(); string CommandText = @"DELETE FROM Friends WHERE ID = " + RV + ""; cmd = new OleDbCommand(CommandText, DbConnection); cmd.ExecuteNonQuery(); dataGridView1.Columns.Clear(); MessageBox.Show(txtName.Text + " was deleted!"); ClearFields(); } } //CREATE NEW RECORD private void btnNew_Click(object sender, EventArgs e) { panel3.Enabled = false; panel2.Enabled = true; panel1.Enabled = true; ClearFields(); dataGridView1.Columns.Clear(); } //UPDATE RECORD public void btnUpdate_Click(object sender, EventArgs e) { if (txtName.Text != "" & txtPhone.Text != ""){ while (IntegrityCheck() == false) { return; } int RV = Convert.ToInt32(RecordValue); //open db connection OpenDBConnection(); string CommandText = @"UPDATE Friends SET Name ='" + txtName.Text + "',Phone ='" + txtPhone.Text + "' WHERE ID = " + RV + ""; cmd = new OleDbCommand(CommandText, DbConnection); cmd.ExecuteNonQuery(); dataGridView1.Columns.Clear(); MessageBox.Show(txtName.Text + " was updated!"); strGlobalName = txtName.Text; UpdateDatagridview(); } else { //MessageBox.Show("Both data elements have NOT been entered!"); MessageBox.Show("Missing data. Please try again."); } } //UPDATE DATAGRIDVIEW private void UpdateDatagridview() { ClearFields(); dataGridView1.Columns.Clear(); //open db connection OpenDBConnection(); string CommandText = @"SELECT * FROM Friends WHERE Name = " + "'" + strGlobalName + "'"; cmd = new OleDbCommand(CommandText, DbConnection); cmd.ExecuteNonQuery(); dr = cmd.ExecuteReader(CommandBehavior.CloseConnection); int columnCount = 3; dataGridView1.ColumnCount = columnCount; string[] rowData = new string[columnCount]; while (dr.Read()) { for (int k = 0; k < columnCount; k++) { dataGridView1.Columns[0].Name = "ID"; dataGridView1.Columns[1].Name = "Name"; dataGridView1.Columns[2].Name = "Phone"; rowData[0] = dr.GetInt32(0).ToString(); RecordValue = rowData[0]; rowData[1] = dr.GetString(1).ToString(); txtName.Text = rowData[1]; rowData[2] = dr.GetString(2).ToString(); txtPhone.Text = rowData[2]; } //datagrid config SetDataGridView(); //add row data dataGridView1.Rows.Add(rowData); //clear fields ClearFields(); //panel1.Enabled = false; panel2.Enabled = false; } } //ALLOW ROWS IN DATAGRIDVIEW TO UPDATE TXTNAME AND TXTPHONE private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) { //handles the clicking on datagridview records and assigning them to txtVariables DataGridViewRow row = this.dataGridView1.Rows[e.RowIndex]; //assigns to txtName txtName.Text = row.Cells[1].Value.ToString(); //assigns to txtPhone txtPhone.Text = row.Cells[2].Value.ToString(); panel1.Enabled = true; } //CLOSE DATABASE private void Form1_FormClosing(Object sender, FormClosingEventArgs e) { if (DialogResult == DialogResult.Cancel) //from another event - you can run other code here //MessageBox.Show("from the btnClose_Click event"); DialogResult = 0; { // Close issued from clicking on X switch (MessageBox.Show(this, "Are you sure you want to close?", "Close Databse", MessageBoxButtons.YesNo, MessageBoxIcon.Question)) { //verify what user wants to do case DialogResult.No: //no to close e.Cancel = true; //MessageBox.Show("User selected No"); break; default: //yes to close //MessageBox.Show("User selected Yes"); break; } } } private void btnClose_Click(object sender, EventArgs e) { //this will call the Form1_FormClosing event Close(); } } }
Program.cs Code
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Threading; using System.Windows.Forms; using System.Data.SqlClient; namespace WindowsFormsApplication13 { static class Program { public static string cnstr; public static string help; /// <summary> /// The main entry point for the application. /// </summary> /// [STAThread] public static void Main() { cnstr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source='c:\\users\\home\\documents\\visual studio 2015\\Projects\\WindowsFormsApplication13\\WindowsFormsApplication13\\friends.accdb'"; help = "c:\\users\\home\\documents\\visual studio 2015\\Projects\\WindowsFormsApplication13\\WindowsFormsApplication13\\friends.accdb"; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } }
Form1.Designer.cs Code
namespace WindowsFormsApplication13 { partial class Form1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing & (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.btnSave = new System.Windows.Forms.Button(); this.dataGridView1 = new System.Windows.Forms.DataGridView(); this.friendsBindingSource = new System.Windows.Forms.BindingSource(this.components); this.friendsDataSet = new WindowsFormsApplication13.friendsDataSet(); this.friendsTableAdapter = new WindowsFormsApplication13.friendsDataSetTableAdapters.FriendsTableAdapter(); this.panel1 = new System.Windows.Forms.Panel(); this.lblPhone = new System.Windows.Forms.Label(); this.lblName = new System.Windows.Forms.Label(); this.txtPhone = new System.Windows.Forms.TextBox(); this.txtName = new System.Windows.Forms.TextBox(); this.panel2 = new System.Windows.Forms.Panel(); this.btnClose = new System.Windows.Forms.Button(); this.txtSearch = new System.Windows.Forms.TextBox(); this.btnSearch = new System.Windows.Forms.Button(); this.btnUpdate = new System.Windows.Forms.Button(); this.btnDelete = new System.Windows.Forms.Button(); this.btnNew = new System.Windows.Forms.Button(); this.panel3 = new System.Windows.Forms.Panel(); this.lblSearch = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.friendsBindingSource)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.friendsDataSet)).BeginInit(); this.panel1.SuspendLayout(); this.panel2.SuspendLayout(); this.panel3.SuspendLayout(); this.SuspendLayout(); // // btnSave // this.btnSave.Location = new System.Drawing.Point(20, 9); this.btnSave.Name = "btnSave"; this.btnSave.Size = new System.Drawing.Size(75, 23); this.btnSave.TabIndex = 2; this.btnSave.Text = "Save"; this.btnSave.UseVisualStyleBackColor = true; this.btnSave.Click += new System.EventHandler(this.btnSave_Click); // // dataGridView1 // this.dataGridView1.Location = new System.Drawing.Point(13, 12); this.dataGridView1.Name = "dataGridView1"; this.dataGridView1.Size = new System.Drawing.Size(350, 138); this.dataGridView1.TabIndex = 13; this.dataGridView1.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellContentClick); // // friendsBindingSource // this.friendsBindingSource.DataMember = "Friends"; this.friendsBindingSource.DataSource = this.friendsDataSet; // // friendsDataSet // this.friendsDataSet.DataSetName = "friendsDataSet"; this.friendsDataSet.SchemaSerializationMode = System.Data.SchemaSerializationMode.IncludeSchema; // // friendsTableAdapter // this.friendsTableAdapter.ClearBeforeFill = true; // // panel1 // this.panel1.Controls.Add(this.lblPhone); this.panel1.Controls.Add(this.lblName); this.panel1.Controls.Add(this.txtPhone); this.panel1.Controls.Add(this.txtName); this.panel1.Controls.Add(this.panel2); this.panel1.Location = new System.Drawing.Point(12, 208); this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(336, 77); this.panel1.TabIndex = 2; // // lblPhone // this.lblPhone.AutoSize = true; this.lblPhone.Location = new System.Drawing.Point(5, 44); this.lblPhone.Name = "lblPhone"; this.lblPhone.Size = new System.Drawing.Size(38, 13); this.lblPhone.TabIndex = 3; this.lblPhone.Text = "Phone"; // // lblName // this.lblName.AutoSize = true; this.lblName.Location = new System.Drawing.Point(4, 9); this.lblName.Name = "lblName"; this.lblName.Size = new System.Drawing.Size(35, 13); this.lblName.TabIndex = 2; this.lblName.Text = "Name"; // // txtPhone // this.txtPhone.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.friendsBindingSource, "Phone", true)); this.txtPhone.Location = new System.Drawing.Point(45, 40); this.txtPhone.Name = "txtPhone"; this.txtPhone.Size = new System.Drawing.Size(179, 20); this.txtPhone.TabIndex = 1; // // txtName // this.txtName.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.friendsBindingSource, "Name", true)); this.txtName.Location = new System.Drawing.Point(45, 6); this.txtName.Name = "txtName"; this.txtName.Size = new System.Drawing.Size(179, 20); this.txtName.TabIndex = 0; // // panel2 // this.panel2.Controls.Add(this.btnSave); this.panel2.Location = new System.Drawing.Point(230, 29); this.panel2.Name = "panel2"; this.panel2.Size = new System.Drawing.Size(106, 37); this.panel2.TabIndex = 4; // // btnClose // this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; this.btnClose.Location = new System.Drawing.Point(169, 16); this.btnClose.Name = "btnClose"; this.btnClose.Size = new System.Drawing.Size(75, 23); this.btnClose.TabIndex = 3; this.btnClose.Text = "Close"; this.btnClose.UseVisualStyleBackColor = true; this.btnClose.Click += new System.EventHandler(this.btnClose_Click); // // txtSearch // this.txtSearch.Location = new System.Drawing.Point(57, 170); this.txtSearch.Name = "txtSearch"; this.txtSearch.Size = new System.Drawing.Size(179, 20); this.txtSearch.TabIndex = 0; // // btnSearch // this.btnSearch.Location = new System.Drawing.Point(262, 168); this.btnSearch.Name = "btnSearch"; this.btnSearch.Size = new System.Drawing.Size(75, 23); this.btnSearch.TabIndex = 1; this.btnSearch.Text = "Enter"; this.btnSearch.UseVisualStyleBackColor = true; this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click); // // btnUpdate // this.btnUpdate.Location = new System.Drawing.Point(7, 16); this.btnUpdate.Name = "btnUpdate"; this.btnUpdate.Size = new System.Drawing.Size(75, 23); this.btnUpdate.TabIndex = 8; this.btnUpdate.Text = "Update"; this.btnUpdate.UseVisualStyleBackColor = true; this.btnUpdate.Click += new System.EventHandler(this.btnUpdate_Click); // // btnDelete // this.btnDelete.Location = new System.Drawing.Point(88, 16); this.btnDelete.Name = "btnDelete"; this.btnDelete.Size = new System.Drawing.Size(75, 23); this.btnDelete.TabIndex = 9; this.btnDelete.Text = "Delete"; this.btnDelete.UseVisualStyleBackColor = true; this.btnDelete.Click += new System.EventHandler(this.btnDelete_Click); // // btnNew // this.btnNew.Location = new System.Drawing.Point(17, 302); this.btnNew.Name = "btnNew"; this.btnNew.Size = new System.Drawing.Size(75, 23); this.btnNew.TabIndex = 10; this.btnNew.Text = "New"; this.btnNew.UseVisualStyleBackColor = true; this.btnNew.Click += new System.EventHandler(this.btnNew_Click); // // panel3 // this.panel3.Controls.Add(this.btnClose); this.panel3.Controls.Add(this.btnUpdate); this.panel3.Controls.Add(this.btnDelete); this.panel3.Location = new System.Drawing.Point(94, 286); this.panel3.Name = "panel3"; this.panel3.Size = new System.Drawing.Size(254, 57); this.panel3.TabIndex = 11; // // lblSearch // this.lblSearch.AutoSize = true; this.lblSearch.Location = new System.Drawing.Point(16, 173); this.lblSearch.Name = "lblSearch"; this.lblSearch.Size = new System.Drawing.Size(41, 13); this.lblSearch.TabIndex = 12; this.lblSearch.Text = "Search"; // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnClose; this.ClientSize = new System.Drawing.Size(375, 364); this.Controls.Add(this.lblSearch); this.Controls.Add(this.panel3); this.Controls.Add(this.btnNew); this.Controls.Add(this.btnSearch); this.Controls.Add(this.txtSearch); this.Controls.Add(this.panel1); this.Controls.Add(this.dataGridView1); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.Name = "Form1"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "Friends Database 1.0 by Eddie Jackson"; this.Load += new System.EventHandler(this.Form1_Load); ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.friendsBindingSource)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.friendsDataSet)).EndInit(); this.panel1.ResumeLayout(false); this.panel1.PerformLayout(); this.panel2.ResumeLayout(false); this.panel3.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.DataGridView dataGridView1; private friendsDataSet friendsDataSet; private System.Windows.Forms.BindingSource friendsBindingSource; private friendsDataSetTableAdapters.FriendsTableAdapter friendsTableAdapter; private System.Windows.Forms.TextBox txtPhone; private System.Windows.Forms.TextBox txtName; private System.Windows.Forms.TextBox txtSearch; private System.Windows.Forms.Label lblPhone; private System.Windows.Forms.Label lblName; private System.Windows.Forms.Label lblSearch; private System.Windows.Forms.Button btnSave; private System.Windows.Forms.Button btnUpdate; private System.Windows.Forms.Button btnSearch; private System.Windows.Forms.Button btnClose; private System.Windows.Forms.Button btnDelete; private System.Windows.Forms.Button btnNew; private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Panel panel2; private System.Windows.Forms.Panel panel3; } }
app.config Code
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> </configSections> <connectionStrings> <add name="WindowsFormsApplication13.Properties.Settings.friendsConnectionString" connectionString="Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\friends.accdb" providerName="System.Data.OleDb" /> </connectionStrings> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> </startup> </configuration>
More about classes and methods
— assigning multiple objects to one class; understanding null
using System; namespace ConsoleApplication9 { class Program { static void Main(string[] args) { Car myCar = new Car(); myCar.Make = "Oldsmobile"; myCar.Model = "Cutlass Supreme"; myCar.Year = 1986; myCar.Color = "Silver"; Car myOtherCar; myOtherCar = myCar; Console.WriteLine("{0} {1} {2} {3}", myOtherCar.Make, myOtherCar.Model, myOtherCar.Year, myOtherCar.Color); myOtherCar.Model = "98"; Console.WriteLine("{0} {1} {2} {3}", myCar.Make, myCar.Model, myCar.Year, myCar.Color); myOtherCar = null; Console.ReadLine(); } } class Car { public string Make { get; set; } public string Model { get; set; } public int Year { get; set; } public string Color { get; set; } } }
Expanded classes with constructors
Simply explained before the code…
Fun x;
//what we can do without a constructor
//notice, there are no assigned values
x = new Fun();
//what we want to do is have some assigned values
//this is why you need constructors
x = new Fun(“Haunted Houses”,”Roller Coasters”,”Ferris Wheel”);
Thus, when you want ‘assigned’ values (which, in most cases you will), you need to create a constructor with parameterized variables. The rest is just a matter of syntax.
using System; namespace ConsoleApplication9 { class Program { static void Main(string[] args) { Car myCar = new Car(); //create a new instance of Car Car.myMethod(); /* myCar.Make = "Oldsmobile"; myCar.Model = "Cutlass Supreme"; myCar.Year = 1986; myCar.Color = "Silver"; */ Car myThirdCar = new Car("Ford", "Escape", 2005, "White"); Car myOtherCar; myOtherCar = myCar; Console.WriteLine("{0} {1} {2} {3}", myOtherCar.Make, myOtherCar.Model, myOtherCar.Year, myOtherCar.Color); myOtherCar.Model = "98"; Console.WriteLine("{0} {1} {2} {3}", myCar.Make, myCar.Model, myCar.Year, myCar.Color); myOtherCar = null; Console.ReadLine(); } } class Car { public string Make { get; set; } public string Model { get; set; } public int Year { get; set; } public string Color { get; set; } // Constructor - Notice it has the same name of our Class Car public Car() { //You could load from a configuration file, // a database, etc. this.Make = "Nissan"; } // Constructor - a second constructor, same class name, but different signature (items in the parentheses) public Car(string make, string model, int year, string color) { Make = make; Model = model; Year = year; Color = color; } public static void myMethod() { Console.WriteLine("Called the static MyMethod"); } } }
Creating/Learning about Classes
using System; namespace ConsoleApplication8 { class Program { static void Main(string[] args) { Car myCar = new Car(); //Note, while these are hard coded here, normally a //user would be selecting these myCar.Make = "Oldsmobile"; myCar.Model = "Cutlass Supreme"; myCar.Year = 1986; myCar.Color = "Silver"; Console.WriteLine("{0} {1} {2} {3}", myCar.Make, myCar.Model, myCar.Year, myCar.Color); //decimal value = DeterminedMarketValue(myCar); //Console.WriteLine("{0:C}", value); Console.WriteLine("{0:C}",myCar.DetermineMarketValue()); Console.ReadLine(); } private static decimal DeterminedMarketValue(Car car) { decimal carValue = 100.0M; return carValue; } } class Car { public string Make { get; set; } public string Model { get; set; } public int Year { get; set; } public string Color { get; set; } public decimal DetermineMarketValue() { decimal carValue; if (Year > 1990) carValue = 10000; else carValue = 2000; return carValue; } } }
Handling Date and Time
using System; using System.Text; namespace ConsoleApplication8 { class Program { static void Main(string[] args) { DateTime myValue = DateTime.Now; //Date and Time Console.WriteLine(myValue.ToString()); //Just Date Console.WriteLine(myValue.ToShortDateString()); //Just Time Console.WriteLine(myValue.ToShortTimeString()); //Long Date Form Console.WriteLine(myValue.ToLongDateString()); //Long Time Form Console.WriteLine(myValue.ToLongTimeString()); //Add days to Date Console.WriteLine(myValue.AddDays(3).ToLongDateString()); //Add hours to Time Console.WriteLine(myValue.AddHours(3).ToLongTimeString()); //Subtract days from Date Console.WriteLine(myValue.AddDays(-3).ToLongDateString()); //Extract month Console.WriteLine(myValue.Month); //Use a date time outside of 'Now' DateTime myBirthday = new DateTime(1974, 8, 5); Console.WriteLine(myBirthday.ToShortDateString()); //2nd method to create a date time DateTime myBirthday2 = DateTime.Parse("8/5/1974"); Console.WriteLine(myBirthday2.ToShortDateString()); //determine time diff TimeSpan myAge = DateTime.Now.Subtract(myBirthday2); Console.WriteLine(myAge.TotalDays); Console.ReadLine(); } } }
Handling strings, format, append, replace, substring, currency, trim
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication8 { class Program { static void Main(string[] args) { //string myString = "My \"so-called\" life"; //string myString = "My so-called life \nwith a line break"; //string myString = "My so-called life with a backslash on c:\\"; //string myString = @"My so-called life with a backslash on c:\"; //string myString = String.Format("{0} = {1}", "First", "Second"); //string myString = string.Format("{0:C}", 123.45); //string myString = string.Format("{0:N}", 1234567890); //string myString = string.Format("Percentage: {0:P}", .123); //string myString = string.Format("Phone Number: {0:(###) ###-####}", 1234567890); //string myString = " That summer we took threes across the board "; //myString = myString.Substring(6); //myString = myString.Substring(6, 14); //myString = myString.ToUpper(); //myString = myString.ToLower(); //myString = myString.Replace(" ", "--"); //myString = myString.Remove(6, 14); //remove preceding/trailing white space //myString = String.Format("Length before {0} -- Length after: {1}", // myString.Length, myString.Trim().Length); /* //demonstrating string data type string myString = ""; for (int i = 0; i < 100; i++) { myString += "--" + i.ToString(); } */ //better method to append strings than the above example StringBuilder myString = new StringBuilder(); for (int i = 0; i < 100; i++) { myString.Append("--"); myString.Append(i); } Console.WriteLine(myString); Console.ReadLine(); } } }
Using While iteration, with a menu, and numbers printing and random number guessing game.
using System; namespace ConsoleApplication8 { class Program { static void Main(string[] args) { bool displayMenu = true; while (displayMenu) { displayMenu = MainMenu(); } } private static bool MainMenu() { Console.Clear(); Console.WriteLine("Choose an option:"); Console.WriteLine("1) Printer Numbers:"); Console.WriteLine("2) Guessing Game:"); Console.WriteLine("3) Exit:"); string result = Console.ReadLine(); if (result == "1") { PrintNumbers(); return true; } else if (result == "2") { GuessingGame(); return true; } else if (result == "3") { return false; } else { return true; } } private static void PrintNumbers() { Console.Clear(); Console.WriteLine("Printer numbers"); Console.Write("Type a number:"); int result = int.Parse(Console.ReadLine()); int counter = 1; while (counter > result + 1) { Console.Write(counter); Console.Write("-"); counter++; } Console.ReadLine(); } private static void GuessingGame() { Console.Clear(); Console.WriteLine("Guessing Game!"); Random myRandom = new Random(); int randomNumber = myRandom.Next(1, 11); int guesses = 0; bool incorrect = true; do { Console.WriteLine("Guess a number between 1 and 10: "); string result = Console.ReadLine(); guesses++; if (result == randomNumber.ToString()) incorrect = false; else Console.WriteLine("Incorrect!"); } while (incorrect); Console.WriteLine("Correct! It took you {0} guesses.", guesses); Console.ReadLine(); } } }
Other studies Algorithms; animations. Look into Khan Academy course, Algorithms.
Data types, concatenation, and placeholders.
using System; using static System.Console; namespace ConsoleApplication6 { class Program { static void Main(string[] args) { //string string myString = ("Hello World!"); WriteLine("String is: " + myString); //int int myInt = 30; WriteLine("Int is: " + myInt); //char char myChar = 'X'; WriteLine("Char is: " + myChar); //placeholders string message_1 = "Good morning!"; string message_2 = "Good evening!"; WriteLine("First message: {0}. Second message: {1}", message_1, message_2); //wait for [Enter] key WriteLine("(Press Enter key to continue)"); ReadLine(); } } }
Create and Call a Method
using System; namespace SimpleMethod { class Program { static void Main(string[] args) { HelloWorld(); Console.ReadLine(); } private static void HelloWorld() { Console.WriteLine("Hello world!"); } } }
More methods and reversing arrays.
using System; namespace HelperMethods { class Program { static void Main(string[] args) { Console.WriteLine("The Name Game"); Console.Write("What's your first name? "); string firstName = Console.ReadLine(); Console.Write("What's your last name? "); string lastName = Console.ReadLine(); Console.Write("In what city were you born? "); string city = Console.ReadLine(); /* char[] firstNameArray = firstName.ToCharArray(); Array.Reverse(firstNameArray); char[] lastNameArray = lastName.ToCharArray(); Array.Reverse(lastNameArray); char[] cityArray = city.ToCharArray(); Array.Reverse(cityArray); string result = ""; foreach (char item in firstNameArray) { result += item; } result += " "; foreach (char item in lastNameArray) { result += item; } result += " "; foreach (char item in cityArray) { result += item; } Console.WriteLine("Results: " + result); */ //string reversedFirstName = ReverseString(firstName); //string reversedLastName = ReverseString(lastName); //string reversedCity = ReverseString(city); //DisplayResult(reversedFirstName, reversedLastName, reversedCity); //or this DisplayResult( ReverseString(firstName), ReverseString(lastName), ReverseString(city)); Console.ReadLine(); } private static string ReverseString(string message) { char[] messageArray = message.ToCharArray(); Array.Reverse(messageArray); return String.Concat(messageArray); } private static void DisplayResult( string reversedFirstName, string reversedLastName, string reversedCity) { Console.Write("Results: "); Console.Write(String.Format("{0} {1} {2}", reversedFirstName, reversedLastName, reversedCity)); } } }
Today’s lab work: Iterations and Arrays
using System; namespace ForInteration { class Program { static void Main(string[] args) { /* for (int i = 0; i < 10; i++) //Console.WriteLine(i); if (i == 7) { Console.WriteLine("Found seven!"); break; } Console.ReadLine(); */ /* int[] numbers = new int[5]; numbers[0] = 4; numbers[1] = 8; numbers[2] = 15; numbers[3] = 16; numbers[4] = 23; //Console.WriteLine(numbers[1]); Console.WriteLine(numbers.Length); Console.ReadLine(); */ //int[] numbers = new int[] { 4, 8, 15, 16, 23, 42 }; //string[] names = new string[] { "Eddie", "Alex", "Michael", "David Lee" }; /* for (int i = 0; i < names.Length; i++) { Console.WriteLine(names[i]); } Console.ReadLine(); */ /* foreach (string name in names) { Console.WriteLine(name); } Console.ReadLine(); */ string zig = "You can get what you want out of life" + " if you help othe people get what they want."; char[] charArray = zig.ToCharArray(); Array.Reverse(charArray); foreach (char zigChar in charArray) { Console.Write(zigChar); } Console.ReadLine(); } } }
Create, write, append to text file. Read items into array. Return items from array.
using System; using System.IO; class Test { public static void Main() { string path = @"c:\CSharpLabs\computers.txt"; // See if file exists, if not exists, create file if (!File.Exists(path)) { // Create a file to write to. string[] createText = { "computer1", "computer2", "computer3" }; File.WriteAllLines(path, createText); } // Append to last line string appendText = "computer99" + Environment.NewLine; File.AppendAllText(path, appendText); // Read each line string[] readText = File.ReadAllLines(path); foreach (string s in readText) { //output to screen Console.WriteLine(s); } //select a couple of array items to output Console.WriteLine("Array 1 is: {0}", readText[0]); Console.WriteLine("Array 2 is: {0}", readText[1]); Console.ReadLine(); } }
A Windows Universal App project I just started as well…more to come later on this. This is from the Visual C# book I’m reading (I’m on page 25).
Notes
Universal App – Next, add code to the button, click event.
General concepts in C#. These are some things I use in software packaging.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; //used by Thread.Sleep using System.Threading.Tasks; using System.IO; using System.Diagnostics; //used by Process using System.Windows.Forms; //used by MessageBox using Microsoft.Win32; //used by Registry namespace PlayingAround { class ReadAll { public static void Main(string[] args) { Console.Out.WriteLine("DISPLAY CONTENTS OF A TEXT FILE"); //creates {contents} variable string contents = File.ReadAllText(@"C:\test.txt"); //outputs {contents} to screen Console.Out.WriteLine("contents = " + contents); Thread.Sleep(10000); //wait 10 seconds //will wait for {ENTER} key //Console.In.ReadLine(); Console.Out.WriteLine("DISPLAY TIMESTAMP"); //creates {DateTime} variable DateTime dt = DateTime.Now; //outputs {DataTime} to screen Console.WriteLine("Current Time is {0} ", dt.ToString()); Console.Out.WriteLine(""); Console.Out.WriteLine(""); Thread.Sleep(5000); //wait 5 seconds Console.Out.WriteLine("LAUNCH and KILL PROCESS"); //launch cnn website using IE Process process1 = Process.Start("iexplore.exe", "www.cnn.com"); Thread.Sleep(7000); //wait 7 seconds foreach (System.Diagnostics.Process IEProc in System.Diagnostics.Process.GetProcesses()) { if (IEProc.ProcessName == "iexplore") { //if IE is found, kill it IEProc.Kill(); //kill IExplore.exe } } //launch notepad.exe - will stay open Process process2 = Process.Start("notepad.exe"); //wait for process to close before continuing process2.WaitForExit(); Thread.Sleep(2000); //wait 2 seconds //show simple popup message - //make sure you Add Reference to System.Windows.Forms . under Projects MessageBox.Show("Program has completed!"); //begin event log creation string sSource; string sLog; string sEvent; sSource = "Notepad"; sLog = "Application"; sEvent = "Sample Event"; if (!EventLog.SourceExists(sSource))EventLog.CreateEventSource(sSource, sLog); EventLog.WriteEntry(sSource, sEvent); EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Warning, 234); //write to text log string text = "Text1 " + "Text2"; System.IO.File.WriteAllText(@"C:\log.txt", text); //set registry key const string userRoot = "HKEY_CURRENT_USER"; const string subkey = "RegistrySetValueExample"; const string keyName = userRoot + "\\" + subkey; Registry.SetValue(keyName, "MyKeyName", "A_String_Value_Goes_Here", RegistryValueKind.String); //get registry key string regValue = (string)Registry.GetValue(keyName, "MyKeyName", ""); //show popup message MessageBox.Show(regValue); //delete registry key string regDelete = @"RegistrySetValueExample"; using (RegistryKey key = Registry.CurrentUser.OpenSubKey(regDelete, true)) { if (key == null) { //does not exist } else { //does exist key.DeleteValue("MyKeyName"); } } } } }
Accept user input, use logic for input, use a DO WHILE Loop, with ELSE IF statements.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Decisions { class Program { static void Main(string[] args) { Console.Title = "Behind the Door!"; Console.WriteLine("Eddie's TV Show"); Console.WriteLine("Choose a door: 1, 2, 3: "); string UserValue = Console.ReadLine(); string Success = "1"; string message = ""; do { if (UserValue == "1") { message = "You have won a vacation to Hawaii!"; Success = "0"; } else if (UserValue == "2") { message = "You have won a jetski!"; Success = "0"; } else if (UserValue == "3") { message = "You have won a cruise!"; Success = "0"; } else { Console.WriteLine(""); Console.WriteLine("I did not recognize your answer!"); System.Threading.Thread.Sleep(3000); Console.Clear(); Console.WriteLine("Choose a door: 1, 2, 3: "); UserValue = Console.ReadLine(); } Console.WriteLine(message); } while (Success == "1"); Console.WriteLine(""); Console.WriteLine("Press Enter to exit."); Console.ReadLine(); } } }
Accept user input, perform simple comparison, use IF and ELSE.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Decisions { class Program { static void Main(string[] args) { Console.Title = "Behind the Door!"; Console.WriteLine("Eddie's TV Show"); Console.WriteLine("Choose a door: 1, 2, 3: "); string UserValue = Console.ReadLine(); if (UserValue == "1") { string message = "You won a vacation to Hawaii!"; Console.WriteLine(message); } else { Console.WriteLine("Sorry, there isn't anything there."); } Console.WriteLine(""); Console.WriteLine("Press Enter to exit."); Console.ReadLine(); } } }