C# comboxbox disable item alternative? - c#

I am trying to write a kiosk program for my print center at a school for students to select size and media type and then have it generate a price. I am currently doing this with radio buttons which works fine but we are adding many more options and a drop down list box would be more appropriate. Also, my code for calculating the price is out of control. I would like to set this up so that calculating the price should be easy. Setup is something like this:
File1 - Paper Size (9 options) - Media Type (18 options)
File2, File 3, etc.
I was going to store this in a 3D array filename[]papersize[]media[] for processing the price.
The problem is that not all media types are available in all sizes. I see that you can not disable items in the list. If you pick one size, I can selectively populate the other drop down with or without items, but it changes my index numbers. If I could disable items, I could keep the same index and make an easy loop for processing prices. As it is now I would have to manually specify and loop for each paper size since the media types are different indexes.
I hope this makes sense, I am not really a programmer, I am just trying to make something simple to improve our workflow and accuracy at the print center. I can provide a screen shot of the old program and a mockup of my new program if it would help. Can anyone think of a more elegant solution for this?
Thanks!!
EDIT
Yikes.. Ok, this is ending up to be more difficult than I was expecting: Thanks everyone for your input, it is much appreciated. I did not really expect any responses and there were a lot. Thank You. I attempted the table idea mentioned below but I am not exactly sure how to implement it. I will comment on that post for what I tried. Let me provide more detail in the event that someone else has another idea.
For example of what I am trying to do:
Size = 8.5x11 has media = matte, double sided matte, luster, gloss, acetate, resume
Size = 11x17 has media = same minus acetate and resume
and so on, up to a 60" roll with backlit media and all sorts of stuff.
Price for 8.5x11 is 1.50 regardless of paper and then each paper has its own price
Price for 11x17 is 3.00 and each paper has its own price which is more than their 8.5x11 counterparts
8.5x11 matte = .25
11x17 matte = .50
8.5x11 matte total = 1.75
11x17 matte total = 3.50
I am trying to do this in as little steps as possible. Currently I have radio buttons which take up a bunch a screen real-estate and do things like: When 11x17_1.Checked acetate_1.Disable, etc. Also for calculating price I have hundreds of lines of code doing things like:
If(8.5x11_1.Checked)
{
If(matte_1.Checked)
price = 8.5x11matte_1;
if(luster_1.Checked)
price = 8.5x11luster_1;
...etc.
}
Rolls require more data (height) to be processed as we charge by linear inch for these. Currently for each file I just have a height box that they are required to fill out. I could just put a height field next to each file for my new version. Then if they select a roll, the height box bust be filled out, which requires more IF's... which I currently have hundreds of. Any thoughts on a more elegant way to do this?
I just don’t have the programming background to simplify this, but I know this can probably be done in 10 lines of code using an array and drop down lists:
It has been a long time since I used arrays but I was thinking of something like:
Selection[file_1][combobox_size.Index][combobox_media.Index]
I think I would have to manually define each array value since the prices are arbitrary?
[0][0][0] = 1.75
[0][0][1] = 1.75
[0][0][2] = 2.00
And so on.
My winform would have let’s say 12 rows for them to enter a file name and then pick the drop down lists. If filename != null then I will process a price for the file and selections.
So if file 1 was 11x17 gloss my array would be something like:
[0][1][3] which I would have pre-defined with a value of $4.00 for example
If it is a roll then I would just multiply by the required height box.
Is this logic sound or grossly inefficient?
EDIT #3
Ok, almost there I think. Sadly, I was unable to figure out the other solutions offered by the community, but I wrote a "get_index" function that looks like this:
public static int get_index(string index)
{
if (index == "Matte")
return (1);
....
if (index == "Luster")
return (3);
....
else
return (0);
}
in my main program I define prices like this:
for (int x = 0; x < filenum; x++)
{
pricegrid[x, 0, 0] = 1.75; // 8.5x11 Resume
pricegrid[x, 0, 1] = 1.75; // 8.5x11 Matte
pricegrid[x, 0, 2] = 1.75; // 8.5x11 Double Sided Matte
pricegrid[x, 0, 3] = 2.35; // 8.5x11 Luster
.....
}
Then to calculate the price I am doing something like this calling that get_index function:
private void calculate_price()
{
getindex[0] = get_index(media1.SelectedItem.ToString());
....
}

You should populate your ComboBox dynamically as you do.
Instead of using SelectedIndex you can use SelectedValue which does not depend on number of elements.
See for example: Using ValueMember in ComboBox

You shouldn't use one three-dimensional array. You will need 3 tables to that. Store all your types in a database.
3 tables are:
1. paper
2. media
3. papermedia
so. you populate first dropdown with papersizes.
then when item is selected in papersizes you run a query to populate dropdown media (you join through intersection table). this way you will only show media that is only available for this papersize. or you can do the other way around.
Does this answer your question?

There are several ways of doing it.
You could create a class FileWithDetail that'd store
[class File / class paper size / class Mediatype ]
Initialize your list at the start of your app
List<FileWithDetail> LstFileWithDetail = new FileWithDetail(){...}
Then with Linq to Object you would easily be able to query the object and bind it to your comboboxes according to your selected value
var LstPaperSize = from p in FileWithDetail
where p.FileName == SelectedFileName
Select ...

Related

How do I add decimals in Xamarin Forms Entries using C#

For starters I'm very very new to writing code! :)
What I have so far...
So far I've used Xamarin.Forms to create a user interface for a sort of specialized calculator. I'm using a Grid Layout containing: a first column of Labels, a second column of Entries (that I have named in Xaml), and a third column of Steppers (so I can change the entries by typing or using the stepper). These 3 views on each row repeat for several rows with different label text on each row and at the bottom of the Grid Layout I have an Entry for the output.
The problem...
Basically, I want to buy a certain product at different weights and prices...among other criteria....and I want to quickly figure out how much money I'll make at a future possible sale price. Simply put... I'm trying to add/subtract/multiply/divide using Xamarin.Forms Entries. I've looked everywhere and can't seem find anyone giving an example of how to do this. I've tried different methods and usually end with an error of not being able to convert the Xamarin.Forms entry to a string...So I'm back to zero. Can I get an example of a Method where I would be able to add/subtract/multiply/divide 2 Xamarin.Forms Entry views together in the C# code behind? This seems very simple to me...what am I missing??? Is there a thread/article/video somewhere that I haven't found that covers this?? And like I said, I'm very new so the answer is probably very simple.
Thanks in advance!
Steven
Entries deal with strings, not numeric values, so you need to convert them before doing calculations.
var amount = Decimal.Parse(EntryA.Text);
var price = Decimal.Parse(EntryB.Text);
var total = amount * price;
// you can use a format string as an argument to ToString()
// to control the output - ie, how many decimals, commas, etc
LabelTotal.Text = total.ToString();
In a real app you will want to validate the input in case the user enters text instead of a value number (the Parse method will throw an exception if the input is bad);

Making a jukebox, adding track list to list box from .text file

Right I am relatively new to programming and I am currently in the middle of my second assignment which is to create a jukebox using arrays, list boxes, media player, text box's, timers and menustrip. I have a number of text files that are laid out like this
2
Other
Big Bad John (1961) - Jimmy Dean.mp3
My Ding A Ling - Chuck Berry.mp3
The first line is the amount of tracks and the second is the genre of the tracks the rest is the actual tracks, what I need to do is display the tracks in a list box and when I use the scroll bar of the list box have it display the next set of tracks from the following genre.
The following is a small piece of my code,
I currently have some global's
public string MediaPath = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
public int NumberofGenre;
ListBox[] mediaLibrary;
and then I use the number of genre for the columns of the array if i have done it correctly.
private void JukeBox_Load(object sender, EventArgs e)
{
StreamReader inputStream = File.OpenText(#"C:\Users\James Dunn\Documents\Visual Studio 2012\Projects\Assignment 2(1)\Assignment 2\MyJukeBox\bin\Genre amount.txt");
NumberofGenre = Convert.ToInt32(inputStream.ReadLine());
mediaLibrary = new ListBox[NumberofGenre];
}
If anyone can give me any help in displaying the tracks that are listed in my text file in my listbox, it would be much appreciated. It will likely require me to skip the first 2 lines as i only want to display the track names. I have spent a days going over lectures and the general internet and I am at a loss.
For a single file you would do these things:
1 read all lines into a string array
2 (optional) check if the total number of lines is lines1 + 1
3 (optional) show line2 in a label
4 for each remaining line add it to the listbox
note: line1 is lines[0] etc..
for a whole list of files repeat for each file and listbox.
Here is a starter:
1 - string[] lines = File.ReadAllLines("firstFile.txt");
..
4 - for (int l = 2; l < lines.Length; l++) mediaLibrary[0].Items.Add(lines[l]);
(Don't worry about global variables; at your current level you probably don't even know how to create them. Your variables are class variables and when used with care perfectly OK..)

Using Lookup or Dictionary to represent a hand of cards in C#

I apologize if there is a similar question already out there. There
are several questions about scoring hands but I don't need that.
The project I am working on takes in 10 cards and needs to report the
best possible 5-card hand found ("straight", "high card", "flush"
etc.). Luckily what the actual hand of cards is is irrelevant, I just
need a name.
I've already parsed and sorted all the cards out and have the tests
for all the possible hands laid out. All I need now is a convenient
way to store the hands. My mad method is as follows, in pseudocode
terms:
I want to have a dynamic list horizontally that I can populate with the NUMBER values of the cards, in order from highest to lowest. For
example, "Q J T 7 4 2 1". T is 10. Duplicates of values will be
ignored. Next, I want each of those values to have, underneath, a
list of the suits of each value that exist in the deck. For example,
J will have a sub-list with the values "D H" to represent that I have
a Jack of Diamonds and a Jack of Hearts.
I believe this to be the most elegant way to deal with these cards,
since most poker hands deal with only values and this way I don't have
to worry about cards of the same value in a row for say the straight
test. Then the two tests that do deal with suit can easily be
tested for by referring to the values under the keys.
Take a deep breath, almost there.
So an instance of Lookup appears to be perfect! It has the exact "one
key to multiple values" structure that I want. However, it doesn't
allow me to add the suits as I come to them. I have to add them all
at once or not at all since the lists are immutable after entry.
So I either
have to find all the suits at once before I even make the Lookup
Somehow add values to the Lookup lists or
Use something else.
Any ideas on any of these?
UPDATE
TL;DR SPARKNOTES VERSION: How can I add more values to the keys inside of a Lookup?
*IMOPRTANT NOTE:*The output of this program should be a string containing the name of the highest hand possible, for example "four of a kind", "two pair" or "high card."
I found one solution (which I unfortunately lost the link to and can't find again) where they suggested re-creating the entire Lookup with the new list. It may just be me but I find that solution to be very... ugly... Anyway several other solutions I have explored or tested are to:
METHOD 1
Roll through and populate another array with the suits associated with each value. Basically (in actual pseudocode this time >_>):
Create an array of ArrayLists (array 1)
Iterate through a sorted string array of "cards" (array 2)
For each card:
Take the char at string index [1] (representing the suit) and add into the ArrayList in array 1 at the index number extracted from string index [0].
This way I have the list of values with associated suits that I wanted. And the list of suits is the minimal size to boot, making iteration through that easier later. With some extra steps I can even make the umbrella array an ArrayList and populate it with the card values in order so there are no gaps and no duplicate numbers. This will leave me with a jagged array of what I want. To be clear, this is not a homework assignment. However, it IS from a coding class project my roommate completed in the past which is why I have the constrictions and requirements I have. Someone else I asked told me SE gets plagued by these kinds of homework questions around this time, so I understand your skepticism. This is a personal project because I want to learn C# (all I know is Java right now, and I like the sound of parameter pointer passing in C# methods, which Java does not do).
If it WERE for a grade I would end there because it works. But I don't really like arraylists of arraylists, they seem messy to me. So I want to know if there is another method.
METHOD 2
I also considered simply dealing with duplicates that inevitably appear. For example, here is my test for a straight:
for (int i = 0; i < 5; i++)
{
int counter = 0;
for (int j = i; j < i + 4; j++)
{
int secondCard = getValue(cardsArray[j + 1]);
int firstCard = getValue(cardsArray[j]);
if (secondCard == firstCard)
{
break;
}
if (secondCard == (firstCard + 1))
{
counter++;
if (counter == 4)
{
isStraight = true;
return "straight";
}
}
}
}
This code does not work. It needs some tweaks somewhere or other to work completely but I want to analyze if it is worth it before I try to fix it. It DOES accurately test for a straight, though. Also a couple notes: firstCard and secondCard are there for readability and debug purposes, and isStraight is there so that I don't reinvent the wheel later when I test for a straight flush.
This nested loop will iterate through all the cards up till the 5th card (since you can't have a straight out of ten sorted cards with less than 5 cards) and then check the next five cards as you would expect. If during this iteration I encounter a duplicate entry it means that it's the same card of another suit and I simply "break". What SHOULD happen as a result of this one statement is that now we have incremented our second iteration by one to check the next card instead of the current one. The count of in-order cards that we have will stay the same so that a list like " 1D 2D 3S 3H 4D 5C" will skip over the second 3 when finding the straight. Despite the break I was actually quite pleased with the elegance of this solution, whether I had a right to be or not.
It all goes back to the flaws of using a simple array of strings ("cards"), which is what my code is tailored to right now. And I hate fixing issues, I'd rather avoid them. Maybe I'm being unnecessarily picky but I'm learning along the way.
METHOD 3
My consideration of the weaknesses of an array of strings lead me to Dictionaries, which looked attractive. It can easily be made to hold my values in order, and easy to find if I have a certain suit for a key (TryGet), all in a neat, tailor-made package. Creating multiple array lists and doing things like "(find index of my value); array1[index].Add(value)" would be replaced by "Dictionary.Add(value, suit)". But I can only add a suit to a key at the point of creation. I couldn't make a "2" key and add "S" and then when I find out the next card is a "2D" add a D under the "2" key. Dictionary just doesn't support that, or even adding multiple values at all. I can make a dictionary of lists, but I still can't edit the list since Dictionaries are mostly query data structures. Lookups support multiple values per key but still cannot be changed after the initial "Add()". Again I could "re-create" the entire lookup or dictionary to add a suit and keep everything in order. But to me that seems like rebuilding the whole bridge because this one cable is too long and I don't have an industrial able cutter. It's a problem that SHOULD have an easier solution, like maybe go and GET some cutters (import a class maybe?).
CONCLUSION
Since you suggest that my needs are no different than what a hand scoring system could deliver leads me to another question:
Are hand scores directly tied to certain hands? Like I mentioned earlier the result I want is "The best hand you can make is a full house" not "This player has the highest hand." So can I calculate the highest scoring hand and extrapolate a "full house" from that score? If so then I guess this is all unnecessary code, but I would kind of like to solve this anyway in that case.
As I wrote this edit it dawned on me that this is basically a vanity issue. I don't "like" the solution I have. I also don't want to use the accepted solution (table lookup) because that is not a coding project that is a copypaste project. I would greatly appreciate any input.
Let's do this the simplest way possible. First, say you have an array of 10 strings, each of which is the name of a card. Like "Four of Hearts" and "Queen of Spades". That's really inconvenient to work with. So the first thing we do is convert those strings to numbers to represent each card. A very convenient way to do it is to use numbers 0-12 for hearts, 13-25 for diamonds, etc. So you have code (possibly a lookup table) that converts names to numbers:
Ace of Hearts = 0
Two of Hearts = 1
Three of Hearts = 2
...
Queen of Hearts = 11
King of Hearts = 12
Ace of Diamonds = 13
...
...
Ace of Clubs = 26
...
...
Kind of Spades = 51
So you have an array of numbers that represents the 10 cards. Call it cardsArray:
int[] cardsArray = new int[10];
// here, fill the cards array from the input
It's easy to check for flushes if you sort by suit and value. Remember, there are only 10 cards, so sorting isn't going to take a huge amount of time. The sort is really easy:
int[] sortedBySuit =
cardsArray
.OrderBy(x => x/13) // sorts by suit
.ThenByDescending(x => x % 13) // then by value, descending
.ToArray();
You can then go sequentially through the array and determine if you have a flush, straight flush, and what the high card in the flush (if any) is.
You have to save that information, because four-of-a-kind beats a flush, for example. So you need to check that, too.
Next, sort by value:
int[] sortedByValue =
cardsArray
.OrderByDescending(x => x % 13)
.ToArray();
Now you can go sequentially through that list to determine high card, pairs, three of a kind, four of a kind, or straights. As you find each type of hand, you save that hand information ("king high straight" or "three tens", along with the hand's value [1 for high card, 2 for pair, straight, flush, full house, etc. in the proper order]) to a list.
Then you just pick the hand with the highest value from those that you found.
That's definitely not the fastest way to do things, but it's simple, uses very little memory, and is fast enough for a prototype. It's certainly simpler than using a dictionary or array of arrays, etc.
To be clear, I didn't read your novel.
TL;DR SPARKNOTES VERSION: How can I add more values to the keys inside of a Lookup?
Usually, when I need a "dictionary" with a key that has multiple values, I use a List<KeyValuePair<string, int>>. You could use LINQ to Objects to select all the values. For example:
static void StackOverflowExample()
{
var cardList = new List<KeyValuePair<string,int>> ()
{
new KeyValuePair<string, int>("Club", 8),
new KeyValuePair<string, int>("Spade", 9),
new KeyValuePair<string, int>("Heart", 10)
};
var results = cardList.Where(p => p.Key == "Heart");
}
var results is an IEnumerable<KeyValuePair<string,int>>. Hopefully, this helps.

A few doubts about charts in C# .NET

I have a few question about charts in .NET in C#, I'm currently working on an app which will display data comming from serial port in real time.
I'm using a simple chart from .NET toolbox with spline series and there are two main feautures which I want to achieve.
The first one - I'd like the comming data points to be displayed on the right part of the chart and I'd like them to move to the left as the new data comes, I don't know how to describe it properly, I hope you can get the main idea since I can't post images yet.
I've achieved this kind of behaviour by reloading all the data points each time I refresh the chart, at first they are all empty and as the data comes I put the bigger and bigger queue of values in the end.
To clarify that the code may be like that:
chartAccelerationX.Series["XSeries"].Points.Clear();
dataPointTable = dataPointQueue.ToArray();
for (int i = 0; i < 1000; i++)
{
DataPoint dataPointX = new DataPoint();
if (1000 - dataPointTable.Length < i)
{
dataPointX.SetValueXY(i + 1, dataPointTable[i - 1000 + dataPointTable.Length].x);
}
else
{
dataPointX.IsEmpty = true;
}
chartAccelerationX.Series["XSeries"].Points.Add(dataPointX);
}
chartAccelerationX.Update();
It works pretty well, but as I said, I'm creating all the 1000 data points each time I update the chart (and I do it every 100ms) so it's probably disastrous in terms of performance (I'll need to have about 6-8 charts in total) and it's limited by the exact number od data points (1000 here).
Isn't there any easier way to achieve something like that with increasing amount of data points dynamically and with the second feature that I wanted to have - an auto matching scroll bar showing for example only 50 records at once?
I've been using a scrollbar as well, but it was just set to show 50 records out of 1000 and I could have scroll through all these empty data points right now.
I can probably make the scrollbar appear after an exact number of data points are on the chart and update it every time the data is added but maybe theres any easier way?
I hope you understood what I was trying to say, I'm still working on my English.
If you can use WPF, there is http://dynamicdatadisplay.codeplex.com/ and for the older WPF version http://dynamicdatadisplay.codeplex.com/wikipage?title=D3v1
which is pretty good, I've used it for some pretty high speed data sampling before

how to improve performance of Tchart in real-time plotting?

I am developing an application which has minimum one tchart with 4 fastlines in it . maximum number of tcharts are 16 depending on few criteria.each fastline contains different sample numbers in different cases. here is the problem now. If I have sample number less than 200-250. then I can see the graph is being plotted real-time. now as the sample number increases the delay goes so long in plotting the graph. so let's say if we have 1000 samples for each fasline then total of 4000 samples in chart. and there can be maximum 16 charts like this. I noticed that delay is highly dependent on number of samples fastline contains and number of fastlines in the chart.
I already made changes regarding autorepaint = false. I have chart1.autorepaint = false
series1.autorepaint = false and also series 2 , 3, 4.
each time I add a value in fastline , I have to manually do chart1.refresh() which takes so much time again as it refreshes all the 4 fastlines in it.
Delay can also be related to series1.add(),
but I am not sure.
Is there anything I can do to avoid the delays ?
Here is the code I am using .
public void PlotActualValuesUpToSampleNumber(int SampleNumber)
{
int DataPoint;
Chart1.AutoRepaint = false;
for (DataPoint = LastActualSamplePlotted + 1; DataPoint <= SampleNumber; DataPoint ++ )
{
if (Imp.ThisSampleContainsFault[ChannelNumber, DataPoint])
{
Chart1.Panel.Gradient.Visible = false;
Chart1.Panel.Color = Imp.ChartBackgroundColorIfFault;
}
Series4.Add(Imp.ActualValue[ChannelNumber, DataPoint], "", Color.Yellow);
LastActualSamplePlotted ++;
}
Chart1.Refresh();
Chart1.AutoRepaint = true;
}
Is there anything I can do to avoid the delays?
I already referred to these links.
http://www.teechart.net/reference/articles/VCLRealtime.htm http://www.teechart.net/support/viewtopic.php?p=47388 http://www.teechart.net/support/viewtopic.php?t=5127 http://stackoverflow.com/questions/11977423/performance-issue-with-tchart
but no success.
Performance is mainly affected by the amount of data the chart has to handle. Different code solutions and environments may also be pretty influential here. So my suggestions are:
Have you tried injecting data arrays directly into the series as the second example Sandra posted here? This is the same principle as in the VCL Real-time Charting article.
have you tried the Direct 2D version of TeeChart? You can find a white paper regarding its performance here.
I'd strongly recommend you to check the examples at the sections below in the features demo available at TeeChart's program group.
*All Features\Welcome !\Chart styles\Standard\Fast Line*
All Features\Welcome !\Speed
If you still don't get the results you expected please send us a simple example project we can run "as-is" to reproduce the problem here.

Categories

Resources