|
I think you're doing fine. When a Control manages/hosts a set of other Controls, my preference is to keep the hosted controls (your 'Item) as "dumb" as possible, and to centralize their management by code in the container Control. So the 'Item might look like this:
public ToDo()
{
InitializeComponent();
CbxDone = cbxDone;
LblID = lblId;
BtnClose = btnClose;
TxtBx = textBox1;
}
public CheckBox CbxDone { set; get; }
public Label LblID { set; get; }
public Button BtnClose { set; get; }
public TextBox TxtBx { set; get; } In the host container the 'Add button handler might look like this:
private void btnAdd_Click(object sender, EventArgs e)
{
ToDo todo = new ToDo();
currentToDos.Add(todo);
currentToDo = todo;
todo.LblID.Text = (idCount).ToString();
idCount++;
todo.Enter += TodoOnEnter;
todo.Leave += TodoOnLeave;
todo.BtnClose.Click += BtnCloseOnClick;
todo.CbxDone.CheckStateChanged += CbxDoneOnCheckStateChanged;
todopanel.Controls.Add(todo);
todo.Dock = DockStyle.Top;
todo.BringToFront();
this.ActiveControl = todo;
} When you close one of the hosted controls"
currentToDos.Remove(currentToDo);
this.todopanel.Controls.Remove(currentToDo);
currentToDo.Dispose();
this.Invalidate(); I would keep track of the hosted controls in several ways: I might keep separate lists for completed tasks, incomplete tasks, selected tasks, and, I might even not destroy tasks, but either disable them while leaving them visible), or keep the ones removed from the display list in a list for future use. Your choices will depend on what you want your app to do, how you want to preserve the state of the controls and their data when the app closes, etc.
In production code, I would be concerned about making the hosted controls only accessible to the host, through design-time attributes like:
[DesignTimeVisible(false)]
public partial class ToDo : UserControl
And other techniques.
«... thank the gods that they have made you superior to those events which they have not placed within your own control, rendered you accountable for that only which is within you own control For what, then, have they made you responsible? For that which is alone in your own power—a right use of things as they appear.» Discourses of Epictetus Book I:12
|
|
|
|
|
Thanks again. This is what I did so far:
Item.cs
using System.Windows.Forms;
namespace ToDo
{
public partial class Item : UserControl
{
public Panel ItemPanel { set; get; }
public CheckBox DoneCheckBox { set; get; }
public Button DeleteButton { set; get; }
public TextBox UserTextBox { set; get; }
public Item()
{
InitializeComponent();
ItemPanel = itemPanel;
DoneCheckBox = doneCheckBox;
DeleteButton = deleteButton;
UserTextBox = userTextBox;
}
}
}
ItemContainer.cs
List<Item> itemList = new List<Item>();
Item crtItem;
void AddItem()
{
if (inputTextBox.Text != "")
{
Item item = new Item();
itemList.Add(item);
crtItem = item;
item.Dock = DockStyle.Top;
item.UserTextBox.Text = inputTextBox.Text;
item.Enter += Item_Enter;
item.Leave += Item_Leave;
item.DoneCheckBox.CheckedChanged += DoneCheckBox_CheckedChanged;
item.DeleteButton.Click += DeleteButton_Click;
itemPanel.Controls.Add(item);
item.BringToFront();
inputTextBox.Text = "";
itemsLabel.Text = itemList.Count + " item(s)";
}
inputTextBox.Focus();
}
private void Item_Enter(object sender, EventArgs e)
{
crtItem.ItemPanel.BackColor = Color.FromArgb(200, 233, 253);
crtItem.UserTextBox.BackColor = Color.FromArgb(200, 233, 253);
}
private void Item_Leave(object sender, EventArgs e)
{
crtItem.ItemPanel.BackColor = Color.FromArgb(240, 240, 240);
crtItem.UserTextBox.BackColor = Color.FromArgb(240, 240, 240);
}
private void DoneCheckBox_CheckedChanged(object sender, EventArgs e)
{
if (crtItem.DoneCheckBox.Checked)
{
crtItem.UserTextBox.ForeColor = Color.FromArgb(150, 150, 150);
crtItem.UserTextBox.Font = new Font("Segoe UI", 18F, FontStyle.Strikeout, GraphicsUnit.Point, 0);
}
else
{
crtItem.UserTextBox.ForeColor = Color.FromArgb(0, 0, 0);
crtItem.UserTextBox.Font = new Font("Segoe UI", 18F, FontStyle.Regular, GraphicsUnit.Point, 0);
}
}
private void DeleteButton_Click(object sender, EventArgs e)
{
itemList.Remove(crtItem);
itemPanel.Controls.Remove(crtItem);
crtItem.Dispose();
Invalidate();
}
The problem is with this crtItem (in your example: currentToDo ). How do I update its value when I click a random Item usercontrol? Here's the VC solution: download[^] Feel free to modify it if you want.
|
|
|
|
|
Your making good progress. My goal here is to provide just enough of a hint for you to finish the rest of this yourself, and, hopefully, increase your future skills. So:
alin1 wrote: How do I update its value when I click a random Item usercontrol? Hint : consider the Enter and Leave Events as shown in the code, and think about what is available in those Event Handlers when they are called as the user changes focus at run-time. What is the 'sender parameter ?
Whenever you are problem-solving with Controls and Events, put breakpoints in the Event Handlers so you can see ehen the Event is triggered, and examine the 'sender and the event arguments. If you make a habit of this, you will make quick progress.
Examine the effect of this code in the 'ctor in my example: this.ActiveControl = todo; What Events does that trigger, and how can you use them.
What other user actions could you use to keep track of the current 'Item ?
best, Bill
«... thank the gods that they have made you superior to those events which they have not placed within your own control, rendered you accountable for that only which is within you own control For what, then, have they made you responsible? For that which is alone in your own power—a right use of things as they appear.» Discourses of Epictetus Book I:12
|
|
|
|
|
Meanwhile (before seeing your latest reply) I tried this and it worked:
private void Item_Enter(object sender, EventArgs e)
{
crtItem = (Item)sender;
crtItem.ItemPanel.BackColor = Color.FromArgb(200, 233, 253);
crtItem.UserTextBox.BackColor = Color.FromArgb(200, 233, 253);
}
private void Item_Leave(object sender, EventArgs e)
{
crtItem = (Item)sender;
crtItem.ItemPanel.BackColor = Color.FromArgb(240, 240, 240);
crtItem.UserTextBox.BackColor = Color.FromArgb(240, 240, 240);
}
Is it the correct approach or it's just a hack?
On a side note, I already implemented the filtering (All, Active, Done), the items count label and Clear done items.
modified 12-Feb-18 15:15pm.
|
|
|
|
|
You are rolling now
Think about what is always 'true when you/user Leave one 'Item, and then later Enter another, or the same, 'Item.
Are there any circumstances where you would want to keep track of not only the current active 'Item, but, the previous one ?
«... thank the gods that they have made you superior to those events which they have not placed within your own control, rendered you accountable for that only which is within you own control For what, then, have they made you responsible? For that which is alone in your own power—a right use of things as they appear.» Discourses of Epictetus Book I:12
|
|
|
|
|
Quote: Are there any circumstances where you would want to keep track of not only the current active 'Item, but, the previous one ?
So far, not.
---
What I'm trying to do next is to trigger an autosave function in 2 scenarios: 5 seconds after the user last pressed a key in a TextBox from an Item and when the app is closed. Regarding autosave, would you recommend reading the TextBox + CheckBox properties of each Item or to store these in a separate data structure in ItemContainer and save it?
Thanks to your advice I improved the app a lot: download[^].
|
|
|
|
|
My preference is to not have an auto-save feature, but, to leave it up to the user when to save state, but, as you mention, saving state/data when the app exits can be important. I like the idea of always giving the user choices. What if I make a big mess, and I don't want to over-write the saved state ?
Of course, if your app has an undo/redo/history feature, that's another, more complex, story.
For saving/restoring UI state in WinForms: research 'Settings, 'Configuration techniques. For data, I suggest you implement a 'Data class and use 'DataContract and 'DataMember WCF facilities: lots of good examples of that here.
I recommend you don't post links to your code; in general, none of us here have time to read, and most of us are reluctant to download anything for security reasons.
keep going, Bill
«... thank the gods that they have made you superior to those events which they have not placed within your own control, rendered you accountable for that only which is within you own control For what, then, have they made you responsible? For that which is alone in your own power—a right use of things as they appear.» Discourses of Epictetus Book I:12
|
|
|
|
|
hi
i want check my password is correct or not
if its ok
extract zip file
|
|
|
|
|
You don't "check" to see if the password is OK because 7Zip, or any other zip library, won't tell you. Either the password you attempt is good or it just doesn't work.
|
|
|
|
|
fyi: SevenZipSharp has a 'Check function for this.
«... thank the gods that they have made you superior to those events which they have not placed within your own control, rendered you accountable for that only which is within you own control For what, then, have they made you responsible? For that which is alone in your own power—a right use of things as they appear.» Discourses of Epictetus Book I:12
|
|
|
|
|
Hmmm, learn something new every day.
|
|
|
|
|
SevenZipSharp is long out-of-date: I suggest you research other, newer, actively supported, compression libraries: [^]
But, if you must use it, Look at the SevenZipSharp source code, for the 'Check function, or look on the web for use examples.
And, look into .Net's cryptographic facilities, if you can separate out password stuff from compression stuff.
«... thank the gods that they have made you superior to those events which they have not placed within your own control, rendered you accountable for that only which is within you own control For what, then, have they made you responsible? For that which is alone in your own power—a right use of things as they appear.» Discourses of Epictetus Book I:12
modified 12-Feb-18 8:54am.
|
|
|
|
|
Message Removed
modified 11-Feb-18 3:32am.
|
|
|
|
|
Message Removed
modified 11-Feb-18 3:32am.
|
|
|
|
|
Message Removed
modified 11-Feb-18 3:32am.
|
|
|
|
|
I'm getting an issue when I try to input data into a web page. However the issue is with my primary/foreign key in the database. Any help would be much appreciated.
Error message:
Error:System.Data.SqlClient.SqlException (0x80131904): The INSERT statement conflicted with the FOREIGN KEY constraint "UserIDfk". The conflict occurred in database "\\MAC\HOME\DOCUMENTS\COLLEGE\4TH YEAR\FYP\ITERATION 1\FYP-NEW\FYP-PARKWAY\FYP-PARKWAY\APP_DATA\USERDATA.MDF", table "dbo.Registration", column 'UserID'. The statement has been terminated. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() at FYP_ParkWay.ListSpace.Button1_Click(Object sender, EventArgs e) in \\Mac\Home\Documents\College\4th Year\FYP\Iteration 1\FYP-NEW\FYP-ParkWay\FYP-ParkWay\ListSpace.aspx.cs:line 30 ClientConnectionId:dbdeb098-62a6-45bf-960b-374be8a4e13f Error Number:547,State: 0,Class:16
My primary key is:
CREATE TABLE [dbo].[Registration] (
[UserID] INT IDENTITY (1, 1) NOT NULL,
[Name] NCHAR (20) NULL,
[Surname] NCHAR (20) NULL,
[Email] NCHAR (30) NULL,
[Address] NCHAR (50) NULL,
[Phone] NVARCHAR (50) NULL,
[Password] NCHAR (30) NULL,
CONSTRAINT [pk_UserID] PRIMARY KEY CLUSTERED ([UserID] ASC)
)
The insert statement in which its referring is:
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn.Open();
String insertQuery = "insert into ListSpace (Area,Date,StartTime,EndTime,Picture) values(@area, @date, @startTime, @endTime, @picture)";
SqlCommand com = new SqlCommand(insertQuery, conn);
com.Parameters.AddWithValue("@area", ddlArea.Text);
com.Parameters.AddWithValue("@date", cdrDate.SelectedDate);
com.Parameters.AddWithValue("@startTime", ddlStart.Text);
com.Parameters.AddWithValue("@endTime", ddlEnd.Text);
com.Parameters.AddWithValue("@picture", updPicture.FileBytes);
com.ExecuteNonQuery();
|
|
|
|
|
Based on the error message you're trying to insert a row that tries to refer to a non-existent row in registration.
Ensure that you're adding the rows in correct order. For example add the row in registration table before adding any rows referring to that table.
One way to find the constraint definition and the table that caused the error is to use following query which shows the table and columns for the violated foreign key constraint.
SELECT *
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu
WHERE ccu.CONSTRAINT_NAME = 'UserIDfk'
|
|
|
|
|
I have 5 randomly generated numbers type in text field every time I press a button:
Something like this: 0.5670.9870.3420.5210.07 etc......They represent sensor values in range 0-1V
I would like to split them so that I get something like this:
0.567 0.987 0.342 0.521 0.07
Also I would like to add a line shift so that every time I press the button the number series goes onto next line.
Anybody has an idea ?
This is my main Form1.cs class:
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 DAQ_Simulator
{
public partial class Form1 : Form
{
int counter;
private DateTime datetime;
private DateTime datetime2;
int maxAI = 7;
int maxDI=3;
int maxSid =10;
string sTxt;
string sTxt1;
Sensor[] sObj = new Sensor[10];
public Form1()
{
InitializeComponent();
for (counter = 0; counter < maxSid; counter++)
{
sObj[counter] = new Sensor(counter);
}
}
private void displaySensorData(object sender, EventArgs e)
{
}
private void groupSampl_Enter(object sender, EventArgs e)
{
}
private void textSampling_TextChanged(object sender, EventArgs e)
{
}
private void btnSampling_Click(object sender, EventArgs e)
{
timer1.Interval = 5900;
timer1.Start();
btnSampling.Enabled = false;
sampling();
if (textSampling.Text == "")
{
textSampling.Text = "Sample";
}
datetime2 = DateTime.Now.AddSeconds(5).AddMilliseconds(900);
string time2 = datetime2.Hour + ":" + datetime2.Minute + ":" + datetime2.Second + "." + datetime2.Millisecond;
textSampling.Text =time2;
System.TimeSpan diff1 = datetime2.Subtract(datetime);
}
private void groupLogg_Enter(object sender, EventArgs e)
{
}
private void txtLogging_TextChanged(object sender, EventArgs e)
{
}
private void labelLoggingText_Click(object sender, EventArgs e)
{
}
private void btnLogging_Click(object sender, EventArgs e)
{
}
private void labelSensorValues_Click(object sender, EventArgs e)
{
}
private void textSensorValues_TextChanged(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
btnSampling.Enabled = true;
timer1.Stop();
}
private void sampling()
{
datetime = DateTime.Now;
string time = datetime.Hour + ":" + datetime.Minute + ":" + datetime.Second + "." + datetime.Millisecond;
for (counter = 0; counter < maxAI; counter++)
{
sTxt += sObj[7].GetAnalogValue().ToString("F3");
}
for (counter = 0; counter < maxDI; counter++)
{
sTxt1 += sObj[3].GetDigitalValue().ToString();
}
textSensorValues.Text = time + "\r\n" + sTxt+sTxt1;
}
}
}
This is my Sensor.cs class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DAQ_Simulator
{
public class Sensor
{
double dVal;
int DigVal;
int sId;
Random rSensVal;
public Sensor(int id)
{
sId = id;
rSensVal = new Random(id);
dVal = 0.0F;
}
public double GetAnalogValue()
{
dVal = rSensVal.NextDouble();
return dVal;
}
public double GetDigitalValue()
{
Random ranDigVal = new Random();
DigVal= ranDigVal.Next(0,2);
return DigVal;
}
public int GetSensId()
{
return sId;
}
}
}
|
|
|
|
|
Hi,
rather than struggling with a problem you created yourself (see the line with sTxt+=...getAnalogValue...) you should try and avoid the problem from the start.
I have several ideas:
- don’t concatenate numbers in a string without a separator; by adding a space or some symbol (say #) you could ease the string splitting later on (have a look at the string.Split method!)
- much better yet, don’t confuse your “business logic” with your user interface, i.e. store your measurement results one by one in an appropriate data structure (could be a List<float> or so), and do whatever is required for displaying separately.
|
|
|
|
|
Hi, thanks for the advice.I am new to programming and as you can see don't have too much experience.
I apologize if my questions seem "stupid".
Back to this problem, I managed to "solve" the problem but I don't think the solution is good even though it works when I run the program.
The instructor of this class I am taking told us to use for loops to solve this problem of getting sensor values and ID numbers of the sensors. I did not do that.
I get completely lost when I need to create an array for sensor values and match it with sensor IDs.
Another thing I am struggling with is how to compare dates. I have a time stamp that indicates clock-time for every sample. A sample time is 5,seconds which means I have to disable Sample button for 5,seconds after clicking it. I used Date.Time.Now and tried to compare dates, I basically have to times one that is current and other that is 5,9 seconds ahead., but since both clocks are running I am not able to apply if/else statement to compare them.
Would you please take a look at this code and let me know if there is any nicer way of solving this preferably with loops.
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 DAQ_Simulator
{
public partial class Form1 : Form
{
int counter;
private DateTime datetime;
private DateTime datetime2;
int maxAI = 7;
int maxDI=3;
int maxSid =11;
Sensor[] sObj = new Sensor[11];
public Form1()
{
InitializeComponent();
for (counter = 0; counter < maxSid; counter++)
{
sObj[counter] = new Sensor(counter);
}
}
private void displaySensorData(object sender, EventArgs e)
{
}
private void groupSampl_Enter(object sender, EventArgs e)
{
}
private void textSampling_TextChanged(object sender, EventArgs e)
{
}
private void btnSampling_Click(object sender, EventArgs e)
{
timer1.Interval = 5900;
timer1.Start();
btnSampling.Enabled = false;
sampling();
datetime2 = DateTime.Now.AddSeconds(5).AddMilliseconds(900);
string time2 = datetime2.Hour + ":" + datetime2.Minute + ":" + datetime2.Second + "." + datetime2.Millisecond;
textSampling.Text =time2;
}
private void groupLogg_Enter(object sender, EventArgs e)
{
}
private void txtLogging_TextChanged(object sender, EventArgs e)
{
}
private void labelLoggingText_Click(object sender, EventArgs e)
{
}
private void btnLogging_Click(object sender, EventArgs e)
{
}
private void labelSensorValues_Click(object sender, EventArgs e)
{
}
private void textSensorValues_TextChanged(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
btnSampling.Enabled = true;
timer1.Stop();
}
private void sampling()
{
datetime = DateTime.Now;
string time = datetime.Hour + ":" + datetime.Minute + ":" + datetime.Second + "." + datetime.Millisecond;
double sensVal1 = sObj[1].GetAnalogValue();
double sensVal2 = sObj[2].GetAnalogValue();
double sensVal3 = sObj[3].GetAnalogValue();
double sensVal4 = sObj[4].GetAnalogValue();
double sensVal5 = sObj[5].GetAnalogValue();
double sensVal6 = sObj[6].GetAnalogValue();
double sensVal7 = sObj[7].GetAnalogValue();
int sensVal8 = sObj[8].GetDigitalValue();
int sensVal9 = sObj[9].GetDigitalValue();
int sensVal10 = sObj[10].GetDigitalValue();
String analogSens1 = sensVal1.ToString("F3");
String analogSens2 = sensVal2.ToString("F3");
String analogSens3= sensVal3.ToString("F3");
String analogSens4 = sensVal4.ToString("F3");
String analogSens5 = sensVal5.ToString("F3");
String analogSens6 = sensVal6.ToString("F3");
String analogSens7 = sensVal7.ToString("F3");
String digSens8 = sensVal8.ToString("F0");
String digSens9 = sensVal9.ToString("F0");
String digSens10 = sensVal10.ToString("F0");
textSensorValues.Text += (" " + time + " " + analogSens1 + " " + analogSens2+ " " + analogSens3 + " " + analogSens4+
" "+ analogSens5+" "+analogSens6+" "+ analogSens7+" "+digSens8+" "+digSens9+" "+digSens10+"\r\n");
}
}
}
Sensor class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DAQ_Simulator
{
public class Sensor
{
Random ranDigVal;
double AnalogVal;
int DigVal;
int sId;
Random rSensVal;
public Sensor(int id)
{
sId = id;
rSensVal = new Random(id);
ranDigVal = new Random(id);
AnalogVal = 0.0F;
}
public double GetAnalogValue(double minAnalogVolt=0.00F,double maxAnalogVolt=1.00F)
{
if(minAnalogVolt <= AnalogVal && AnalogVal<= maxAnalogVolt)
AnalogVal = rSensVal.NextDouble();
return AnalogVal;
}
public int GetDigitalValue(int digMin = 0, int digMax = 1)
{
DigVal = ranDigVal.Next(0, 2);
return DigVal;
}
public int GetSensId()
{
return sId;
}
}
}
modified 10-Feb-18 14:09pm.
|
|
|
|
|
Hi,
I have lots of comments, here are just a few:
1. I don't think Sensor.GetAnalogValue() is doing what you think it is doing, I fail to see how the current code could be useful. Maybe you should first add a comment explaining what the method is supposed to do, and only then compare the code with the written description.
2. I see two new Random() statements inside Sensor. They tell me you did not understand the matter that was handled in your earlier thread, two days ago.
This is what the Random class does:
- each NextValue() returns a value assumed to be random, however it is never random, it is pseudo-random, which means anyone knowing the internal code can predict the next value. The values returned are from a huge but fixed and circular list (not stored but calculated), and the only random thing about it is you can influence where in the list the sequence will start, that is what the "seed" does.
- If you provide the same seed to different Random instances, you get the same values returned.
- And if you don't, the .NET Random class will derive a seed from the current time with millisecond resolution. As creating a Random object takes much less than a millisecond, two consecutive new Random() will typically use the same seed.
Normally, the easy way to correctly use Random is by having only one of them, so make it a static field within your Sensor class.
3. If you already know what Properties are, you shouldn't have a method called GetSensId(). If properties still are in your future, then don't bother for now.
4. Having a lot of variables with almost identical names (sensVal#, analogSens#) in general indicates bad design; you should consider avoiding so many variables in the first place, and when you really need them all at the same time, then consider an aggregate, such as an Array. Doing so your code will turn out to be more concise, clearer, and less prone to typing errors.
5. A method that is intended to obtain some values, such as sampling(), normally should make those values available to the other methods and properties of the class; yours doesn't, it has type void, and the only thing coming out of it is a complex string going to the screen. There are many ways to provide values, the obvious one is by using a return statement (you could return an Array of floats, of a List of doubles, or whatever suits you); alternatives are "out" parameters (don't abuse those!), and in some cases class-level variables (not recommended here). I hope you notice how this fits well with the previous comment.
6. You should not export information through a GUI element (such as a TextBox), except towards the program user; a program that shows information to the user in one part of the code, and then tries to regain that information from the GUI is extremely bad design. You should rely on data structures, what the user sees should be an afterthought, and not an essential part of operation.
7. Over time you will learn to carefully choose identifier names; GetAnalogValue() is good, sampling() is not.
Keep learning!
|
|
|
|
|
Why are you converting numbers to strings and then concatenating them all into an unparsable list? The only time you need to convert them to strings is when displaying or printing. Inside your application you should keep them as doubles at all times.
|
|
|
|
|
I need to model multivariate polynomials where the number of variables depends on user input. I found it natural to model univariate polynomials as arrays of numbers representing the coefficients, whose indices represent the degrees of the terms they correspond to. The obvious extension to n-variable polynomials is an n-dimensional array, the index of an entry with respect to a given dimension representing the degree of the term with respect to a given one of the variables. However, it seems like it would be tricky to declare and manipulate such an object - I can't type int[][]...[] (n sets of brackets), after all. Alternatively, I could given up on the idea of encoding term degree in the positions of entries in the data structure, perhaps using a dictionary where the values are the coefficients and the keys are one-dimensional, n-element arrays specifying the degree of the term, but this approach would mean it would be necessary to do a bunch of searches every time the polynomial is operated on, which seems inelegant. Are there any other approaches I should consider?
|
|
|
|
|
I've come up with an n-dimension array class:
class ndArray
{
int Dimensions;
int DimensionLength;
int[] Array;
public ndArray(int dimensions, int dimensionLength)
{
Dimensions = dimensions;
DimensionLength = dimensionLength;
int arrayLength = 1;
for (int i = 0; i < dimensions; ++i)
arrayLength *= dimensionLength;
Array = new int[arrayLength];
}
int getIndex(params int[] indices)
{
int index = 0;
int nsPlace = 1;
for (int i = 0; i < Dimensions; ++i)
{
index += indices[i] * nsPlace;
nsPlace *= DimensionLength;
}
return index;
}
public int getElement(params int[] indices)
{
return Array[getIndex(indices)];
}
public void setElement(int element, params int[] indices)
{
Array[getIndex(indices)] = element;
}
}
I'll have to see how this works in the context of polynomials. Maybe the static limit on dimension length will be a problem.
|
|
|
|
|
|