Altering string array value with radio button - c#

I'm having an issue with altering the value of a string array based on what radio button is selected, it's written in C# using Visual Studio 2013 professional.
Basically all that needs to happen is if the radio button called "smallCarRadBtn" is selected, then the string array call "carSize" has to hold the word "Small", and likewise for the other two radio buttons "medCarRadBtn" and "largeCarRadBtn".
At the moment it is telling me:
"Cannot implicitly convert type 'char' to 'string[]'
I have 'highlighted' the area that contains the code for this with asterisks'*'. Any help would be appreciated.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Assignment2
{
public partial class Form1 : Form
{
TimeSpan daysHiredIn;
DateTime startDate, endDate;
DateTime dateToday = DateTime.Today;
public static string[] names = new string[50];
public static string[] carSize = new string[50];
public static int[] cardNumb = new int[50];
public static int[] cost = new int[50];
public static TimeSpan[] daysHired = new TimeSpan[50];
public static int entryCount = 0, cardNumbIn, carFee = 45, intDaysHired;
public Form1()
{
InitializeComponent();
smallCarRadBtn.Checked = true;
}
private void confirmBtn_Click(object sender, EventArgs e)
{
if (entryCount >= 50)
{
MessageBox.Show("Arrays are Full");//if array is full
}
else if (nameTxtBox.Text == "")
{
MessageBox.Show("You must enter a name");//Nothing entered
}
else if (!int.TryParse(cardNumbTxtBox.Text, out cardNumbIn))
{
MessageBox.Show("You must enter an integer number");
cardNumbTxtBox.SelectAll();
cardNumbTxtBox.Focus();
return;
}
else if (hireStartDatePicker.Value < dateToday)
{
MessageBox.Show("You cannot enter a date earlier than today");
}
else if (hireEndDatePicker.Value < dateToday)
{
MessageBox.Show("You cannot enter a date earlier than today");
}
else
{
*******************************************************************************************
if (smallCarRadBtn.Checked)
{
carSize = ("small"[entryCount]);
}
else if (MedCarRadBtn.Checked)
{
carSize = ("Medium"[entryCount]);
}
else if (largeCarRadBtn.Checked)
{
carSize = ("Large"[entryCount]);
}
*******************************************************************************************
names[entryCount] = nameTxtBox.Text;
cardNumb[entryCount] = cardNumbIn;
endDate = (hireEndDatePicker.Value);
startDate = (hireStartDatePicker.Value);
daysHiredIn = (endDate - startDate);
cost[entryCount] = (carFee * daysHiredIn);
daysHired[entryCount] = daysHiredIn;
entryCount++;
nameTxtBox.SelectAll();
nameTxtBox.Focus();
}
}
private void viewBtn_Click(object sender, EventArgs e)
{
for (entryCount = 0; entryCount < 50; entryCount++)
{
listBox1.Items.Add(names[entryCount]+"\t"+daysHired[entryCount].Days.ToString());
}
}
}
}

carSize is an array of strings but you are trying to assign it a char:
carSize = ("small"[entryCount]);
Here the "small" is a string, and "small"[entryCount] returns the character at the index entryCount
You should change carSize to char[] if you want to stores characters, and set the elements using indexer instead of assigning the array directly. Or if you want to store the text + entryCount then you should concatenate strings:
carSize[index] = "small" + entryCount;
Or if you just want to set carSize[entryCount] then:
carSize[entryCount] = "small";

Related

C# - amend values from column1 in DaraGridView and put them in new column

I have a section of code which splits an input string into rows and outputs it into a DataGridView.
These are all populated into column 1.
I want to further split the values in column 1 into column 2 and 3 etc.
The values for column 2 and 3 need to come from column 1 NOT THE ORIGINAL INPUT.
For example:
EDIT: More example inputs
Input String :
abc12, def, 56, jkl78, mno90
Current Code:
private void Button1_Click(object sender, EventArgs e)
{
List<string> eSplit = new List<string>(eInputBox.Text.Split(new string[] { "," }, StringSplitOptions.None));
DataGridViewTextBoxColumn eOutputGrid = new DataGridViewTextBoxColumn();
eOutputGrid.HeaderText = "Section";
eOutputGrid.Name = "Section";
eOutputDGV.Columns.Add(eOutputGrid);
foreach (string item in eSplit)
{
eOutputDGV.Rows.Add(item);
}
}
Desired Output: (if there is no value then it needs to be blank).
Section Letters Numbers
abc12 abc 12
def def
56 56
jkl78 jkl 78
mno90 mno 90
You have to add each column definition to your eOutputDGV and then to pass three parameters to each eOutputDGV.Row:
private void Button1_Click(object sender, EventArgs e)
{
List<string> eSplit = new List<string>(eInputBox.Text.Split(new string[] { "," }, StringSplitOptions.None));
DataGridViewTextBoxColumn eOutputGrid = new DataGridViewTextBoxColumn();
eOutputGrid.HeaderText = "Section";
eOutputGrid.Name = "Section";
eOutputDGV.Columns.Add(eOutputGrid);
eOutputGrid = new DataGridViewTextBoxColumn();
eOutputGrid.HeaderText = "Letters";
eOutputGrid.Name = "Letters";
eOutputDGV.Columns.Add(eOutputGrid);
eOutputGrid = new DataGridViewTextBoxColumn();
eOutputGrid.HeaderText = "Numbers";
eOutputGrid.Name = "Numbers";
eOutputDGV.Columns.Add(eOutputGrid);
foreach (string item in eSplit)
{
eOutputDGV.Rows.Add(item.Trim(), item.Trim().Substring(0, 3), item.Trim().Substring(3));
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace dgvAlphaNumbericSplit
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
dataGridView1.Rows.Clear();
dataGridView1.Rows.Add("abc12", "", "");
dataGridView1.Rows.Add("def", "", "");
dataGridView1.Rows.Add("56", "", "");
dataGridView1.Rows.Add("jkl78", "", "");
dataGridView1.Rows.Add("mno90", "", "");
}
private void Button1_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if(dataGridView1.Rows[row.Index].Cells[0].Value != null)
{
string str = dataGridView1.Rows[row.Index].Cells[0].Value.ToString();
int index = str.IndexOfAny(new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' });
string chars = "";
string nums = "";
if (index >= 0)
{
chars = str.Substring(0, index);
nums = str.Substring(index);
}
else
{
chars = str;
}
dataGridView1.Rows[row.Index].Cells[1].Value = chars;
dataGridView1.Rows[row.Index].Cells[2].Value = nums;
}
}
}
}
}
Here are the results: -
Assuming you have a list of string, you can shape it into the expected result using a linq query:
dataGridView1.DataSource = list.Select(x=>Process(x)).ToList();
And what is the Process method? It's a static method which is responsible to process the input string and convert it to the desired model, let's say you have a model like this:
public class MyModel
{
public string Letters { get; set; }
public int Numbers { get; set; }
public string Section
{
get
{
return $"{Letters}{Numbers}";
}
}
}
Then the process method is something like this:
pubic static MyModel Process(string s)
{
// some logic to extract information form `s`
return new MyModel(){ Letters = ..., Numbers = ... };
}

How do make the code display the information?

I'm trying to debug the C# code but can't find the logic error of why it's not displaying the data and no error message.
To begin with, the code was in large chunks so I then tried splitting the code into smaller methods but still unable to find the issue of where I'm going wrong.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Drivers_license_exam
{
public partial class Form1 : Form
{
private string[] studentAnsArray = new string[20];
private string[] correctAnsArray = { "B", "D", "A", "A", "C", "A","B", "A", "C", "D", "B","C",
"D", "A", "D", "C","C", "B", "D", "A" };
public Form1()
{
InitializeComponent();
}
private void GetFile(out string fileName)
{
if (openFile.ShowDialog() == DialogResult.OK)
{
fileName = openFile.FileName;
}
else
{
fileName = "";
}
}
private void GetAndReadFile(string fileName)
{
string results;
StreamReader inputFile = File.OpenText(fileName);
while (!inputFile.EndOfStream)
{
results = inputFile.ReadLine();
studentAns.Items.Add(results);
//studentAnsArray[index] = inputFile.ReadLine();
//correctAns.Items.Add(studentAnsArray);
}
foreach (string answers in correctAnsArray)
{
correctAns.Items.Add(answers);
}
inputFile.Close();
}
private int TotCorrect()
{
int correct = 0;
for (int index = 0; index < correctAnsArray.Length; index++)
{
if (studentAnsArray[index]== correctAnsArray[index])
{
correctTxt.Text = index.ToString();
correct++;
}
}
return correct;
}
private int TotIncorrect()
{
int incorrect = 0, questNum = 1;
for (int index = 0; index < correctAnsArray.Length; index++)
{
if (studentAnsArray[index] == correctAnsArray[index])
{
incorrectAns.Items.Add("Question: " + questNum);
incorrectAns.Items.Add("Incorrect");
incorrect++;
}
}
return incorrect;
}
private bool PassedTest()
{
bool pass = false;
if (TotCorrect() >= 15)
{
passFailedTxt.Text = "Passed";
}
if (TotIncorrect() < 15)
{
passFailedTxt.Text = "Failed";
}
return pass;
}
private void displayRes_Click(object sender, EventArgs e)
{
string studentAns;
GetFile(out studentAns);
GetAndReadFile(studentAns);
TotCorrect();
TotIncorrect();
PassedTest();
}
private void exit_Click(object sender, EventArgs e)
{
this.Close();
}
private void Clear_Click(object sender, EventArgs e)
{
}
}
}
What I expected the code to do is output the following:
display the incorrect results
display pass or fail in a text box
display the total of correct and incorrect answers in a text box
The output that I'm getting from this code is:
- doesn't display the incorrect answers in the list box
- displays fail although the answers from the text and the array are correct
- doesn't display the total of correct and incorrect answers

C# List<T> / List<class> get values

I write to my class different values and I would like to get the values of my class. The Debug outputs shows me:
Value: List.data Index 0
Value: List.data Index 1
How I get the real value of my class properties?
My code example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Diagnostics;
namespace List
{
class data
{
public string name { get; set; }
public Rectangle rect { get; set; }
}
class Program
{
static void Main(string[] args)
{
data dat1 = new data();
List<data> listdat = new List<data>();
dat1.name = "test1";
dat1.rect = new Rectangle(10, 10, 10, 10);
listdat.Add(dat1);
data dat2 = new data();
dat2.name = "test2";
dat2.rect = new Rectangle(20, 20, 20, 20);
listdat.Add(dat2);
data dat3 = new data();
dat3.name = "test3";
dat3.rect = new Rectangle(30, 30, 30, 30);
listdat.Add(dat3);
listdat.RemoveAt(1);
foreach (var item in listdat)
{
//This will yield the proper index that you are currently on
int index = listdat.IndexOf(item);
}
foreach (var item in listdat.Select((value, index) => new { Value = value, Index = index }))
{
//Get the value through item.Value;
var currentValue = item.Value;
//Get the index through item.Index;
int currentIndex = item.Index;
Debug.WriteLine("Value: {0} Index {1}", currentValue, currentIndex);
}
int i = 0;
}
}
}
I´m wondering why you use this weird Select-statement rather than a good old-style for-loop which also gives you the index:
for(int i = 0; i < listdat.Count; i++)
{
var currentValue = listdat[i].Name;
int currentIndex = item.Index;
Debug.WriteLine("Value: {0} Index {1}", currentValue, i);
}
You don´t even have to change your data-class-code, simply access the property (probably name in your case) of your current instance listdat[i] and you´re done.
Btw. the following code is useless as the variable index is reset on every loop but never read:
foreach (var item in listdat)
{
//This will yield the proper index that you are currently on
int index = listdat.IndexOf(item);
}
When you just put an object for printing out it will call the objext's ToString() method, which by default just returns the class' name.
If you want it to output something different you have to override.
You can for example add this to the data class:
public override string ToString()
{
return name;
}

How to update a TextView text (decode text effect)?

I need help as mentioned in the title.
I have a timer routine that will update the text of a label. It's a decode text effect, but it doesn't seem to update when the timer routine is executed. I am using C#.
MainActivity.cs
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Text;
using System.Timers;
using System.Linq;
namespace ValidateCreditCardNumber_Android
{
[Activity (Label = "ValidateCreditCardNumber_Android", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
EditText editText;
DecodeTextView resultLabel;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
editText = FindViewById<EditText> (Resource.Id.editText);
Button validateButton = FindViewById<Button> (Resource.Id.validateButton);
resultLabel = FindViewById<DecodeTextView> (Resource.Id.resultLabel);
editText.KeyListener = Android.Text.Method.DigitsKeyListener.GetInstance("0123456789" + System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalDigits);
validateButton.Click += OnNumberEntryCompleted;
}
void OnNumberEntryCompleted(object sender, EventArgs args)
{
var entry = editText;
var resultText = "";
if (Mod10Check (entry.Text)) {
// resultLabel.SetTextColor(Android.Graphics.Color.White);
resultText = "__VALID NUMBER";
} else {
resultText = "INVALID NUMBER";
}
// entry.Enabled = false;
// resultLabel.AnimateText (true, resultText, 10);
RunOnUiThread(() => resultLabel.AnimateText (true, resultText, 10));
}
public static bool Mod10Check(string creditCardNumber)
{
// Check whether input string is null or empty.
if (string.IsNullOrEmpty(creditCardNumber)) {
return false;
}
char[] charArray = creditCardNumber.ToCharArray();
// 1. Starting with the check digit double the value of every other digit
// 2. If doubling of a number results in a two digits number, add up.
// the digits to get a single digit number. This will results in eight single digit numbers.
// 3. Get the sum of the digits.
int sumOfDigits = charArray.Where((e) => e >= '0' && e <= '9')
.Reverse()
.Select((e, i) => ((int)e - 48) * (i % 2 == 0 ? 1 : 2))
.Sum((e) => e / 10 + e % 10);
// If the final sum is divisible by 10, then the credit card number.
// is valid. If it is not divisible by 10, the number is invalid.
return sumOfDigits % 10 == 0;
}
}
}
DecodeTextView.cs
using System;
using System.Text;
using System.Timers;
//using Android.Runtime;
using Android.Content;
using Android.Util;
namespace ValidateCreditCardNumber_Android
{
public class DecodeTextView : Android.Widget.TextView
{
private readonly Timer _timerAnimate = new Timer();
private TextDecodeEffect _decodeEffect;
private bool _showing;
private int _initGenCount;
public int Interval
{
get { return (int)_timerAnimate.Interval; }
set { _timerAnimate.Interval = value; }
}
// protected DecodeTextView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
public DecodeTextView(Context c, IAttributeSet args) : base(c, args)
{
_timerAnimate.Interval = 100;
_timerAnimate.Elapsed += _timerAnimate_Tick;
}
public void AnimateText(bool show, string text, int initGenCount)
{
_initGenCount = initGenCount;
_decodeEffect = new TextDecodeEffect(text) { TextVisible = !show };
Text = _decodeEffect.Peek (DecodeMode.None);
_showing = show;
_timerAnimate.Start ();
}
private void _timerAnimate_Tick(object sender, EventArgs e)
{
if (_initGenCount != 0) {
Text = _decodeEffect.GenerateNumberRange (Text.Length);
_initGenCount--;
return;
}
var decodeMode = _showing ? DecodeMode.Show : DecodeMode.Hide;
var text = _decodeEffect.Peek (decodeMode);
if (text == null) {
_timerAnimate.Stop ();
} else {
Text = text;
}
}
}
public enum DecodeMode
{
None,
Show,
Numbers,
Hide
}
class TextDecodeEffect
{
private int _visibleCount;
private readonly Random _random = new Random ();
public bool TextVisible
{
get { return _visibleCount == OriginalText.Length; }
set { _visibleCount = value ? OriginalText.Length : 0; }
}
public string OriginalText { get; private set; }
public TextDecodeEffect(string text)
{
OriginalText = text;
}
public string Peek(DecodeMode mode)
{
switch (mode) {
case DecodeMode.Numbers:
return GenerateNumberRange (OriginalText.Length);
case DecodeMode.Hide:
if (_visibleCount == 0)
return null;
_visibleCount--;
break;
case DecodeMode.Show:
if (_visibleCount == OriginalText.Length)
return null;
_visibleCount++;
break;
}
var text = GenerateNumberRange (OriginalText.Length - _visibleCount);
text += OriginalText.Substring (OriginalText.Length - _visibleCount, _visibleCount);
return text;
}
public string GenerateNumberRange(int count)
{
var SB = new StringBuilder ();
for (int i = 0; i < count; i++)
SB.Append(_random.Next(0, 10));
return SB.ToString();
}
}
}
Here you can found the project
Please help me to fix this problem :( thank you.
This is a threading issue, you can only change UI elements on the UI thread and the timer callback _timerAnimate_Tick will execute on a background thread.
You can see this by logging the thread ID for DecodeTextViews constructor and its _timerAnimate_Tick method:
public DecodeTextView(Context c, IAttributeSet args) : base(c, args)
{
// ...
Console.WriteLine ("DecodeTextView executing on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
}
private void _timerAnimate_Tick(object sender, EventArgs e)
{
Console.WriteLine ("_timerAnimate_Tick executing on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId);
// ...
}
Which will render the following in the log output:
DecodeTextView executing on thread: 1
_timerAnimate_Tick executing on thread: 6
This is simply fixed by changing the Text property of DecodeTextView on the UI thread using the Post method:
private void _timerAnimate_Tick(object sender, EventArgs e)
{
if (_initGenCount != 0) {
Post (() => {
Text = _decodeEffect.GenerateNumberRange (Text.Length);
});
_initGenCount--;
return;
}
var decodeMode = _showing ? DecodeMode.Show : DecodeMode.Hide;
var text = _decodeEffect.Peek (decodeMode);
if (text == null) {
_timerAnimate.Stop ();
} else {
Post (() => {
Text = text;
});
}
}

Morse code converter only outputs one character c#

I am trying to get the outputLabel to be a label control box where the morse code will output to. I am not sure why only the first morse code character is displayed but not the rest of the code. (if I type "cat" I only get first morse code character in outlabel)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MorseCode
{
public partial class morseCodeForm : Form
{
public morseCodeForm()
{
InitializeComponent();
}
//Anthony Rosamilia
//Make a key,value system to translate the user text.
//Make sure usertext appears only in lower case to minimise errors.
private void convertButton_Click(object sender, EventArgs e)
{
Dictionary<char, String> morseCode = new Dictionary<char, String>()
{
{'a' , ".-"},{'b' , "-..."},{'c' , "-.-."}, //alpha
{'d' , "-.."},{'e' , "."},{'f' , "..-."},
{'g' , "--."},{'h' , "...."},{'i' , ".."},
{'j' , ".---"},{'k' , "-.-"},{'l' , ".-.."},
{'m' , "--"},{'n' , "-."},{'o' , "---"},
{'p' , ".--."},{'q' , "--.-"},{'r' , ".-."},
{'s' , ".-."},{'t' , "-"},{'u' , "..-"},
{'v' , "...-"},{'w' , ".--"},{'x' , "-..-"},
{'y' , "-.--"},{'z' , "--.."},
//Numbers
{'0' , "-----"},{'1' , ".----"},{'2' , "..----"},{'3' , "...--"},
{'4' , "....-"},{'5' , "....."},{'6' , "-...."},{'7' , "--..."},
{'8' , "---.."},{'9' , "----."},
};
string userText = inputTextBox.Text;
userText = userText.ToLower();
for (int index = 0; index < userText.Length; index++)
{
/* if (index > 0)
{
outLabel.Text = ('/').ToString();
}
*/char t = userText[index];
if (morseCode.ContainsKey(t))
{
outLabel.Text = (morseCode[t]);
}
}
}
private void clearButton_Click(object sender, EventArgs e)
{
inputTextBox.Text = "";
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
outLabel.Text = (morseCode[t]);
You're setting the Text property to a completely new value, not appending. Wouldn't it be odd if that assignment did append a string to what was already there?
You need to preserve the old value:
outLabel.Text += morseCode[t];
That, however, creates a new string every time you append. Better solution; build the string up with a StringBuilder first, i.e., a mutable string.
var sb = new StringBuilder();
for (int index = 0; index < userText.Length; index++)
{
var t = userText[index].ToLower();
string morseValue;
// no need for ContainsKey/[], use a single lookup
if (morseCode.TryGetValue(t, out morseValue))
{
sb.Append(morseValue);
}
}
outLabel.Text = sb.ToString();

Categories