I'm currently working on a homework assignment where I need to set up a calculator-type program. It needs to read one or two user-input values (depending on the calculation), and then perform the calculation based on the values.
I currently have
2 textBoxes (tbInput1 and tbInput2),
4 radioButtons,
one button (btnCalc)
a blank label in which the result will be displayed.
Two of the radioButtons (rbtnTrap and rbtnFak) disable the first textBox when checked; the other two need two values to be entered, and for that reason enable both textBoxes when checked. btnCalc is supposed to enable itself when the relevant number of textBoxes have value - the relevant number of textBoxes depends on which radio button is checked.
The problem is that when I check rbtnTrap or rbtnFak (disabling tbInput1) and enter an integer in tbInput2, btnCalc stays disabled.
I'll try to explain what I have so far:
In the _TextChanged event for tbInput1, I have an exact copy of the second if block posted below. tbInput1 is only active when rbtnPot OR rbtnFib are checked, so that control only runs when that is the case.
In the _TextChanged event for tbInput2, I have the below, since tbInput2 is always enabled, and the control must run no matter which radio button is checked, although the control should run differently if i check rbtnTrap OR rbtnFak as opposed to rbtnPot OR rbtnFib.
Or that's my understanding of it. I'm certainly open to suggestions and corrections.
private void tbInput2_TextChanged(object sender, EventArgs e)
{
//For single-field values
if ((rbtnTrap.Checked || rbtnFak.Checked) &&
!string.IsNullOrWhiteSpace(this.tbInput2.Text))
{
btnCalc.Enabled = true;
}
else
{
btnCalc.Enabled = false;
}
// For multi-field values
if ((rbtnPot.Checked || rbtnFib.Checked) &&
(!string.IsNullOrWhiteSpace(this.tbInput1.Text)
&& !string.IsNullOrWhiteSpace(this.tbInput2.Text)))
{
btnCalc.Enabled = true;
}
else
{
btnCalc.Enabled = false;
}
}
Because it is a homework, I am not going to give your the straight answer, but instead a hint: the problem is in the code of the tbInput2_TextChanged event (code that you posted).
When rbtnTrap or rbtnFak are checked, your code will be run following such a path you don't think it will. Set a breakpoint (F9) on the first line of the tbInput2_TextChanged code and run the code step by step (F10) after entering some text in tbInput2.
You will see why your button btnCalc is enabled as you think it is, but disabled in the next moment.
Feel free to comment if you need more help afterwards. :)
EDIT
The problem comes from your if blocks. When one of rbtnTrap and rbtnFak is checked:
your code will run in the if clause of the first block and then do btnCalc.Enabled = true; but...
it will also run in the else clause of the second block (because (rbtnPot.Checked || rbtnFib.Checked) is false) and thus do btnCalc.Enabled = false;.
I'm not sure how much I understand your problem (I'm sorry, the explanation was a bit all over the place), but one thing that I do see, is that you're only implementing your tests in one event when you have two controls to check.
It sounds like a simple problem, but I really can't understand what is implemented where and who is supposed to do what, so if my 2 cents above were useless and you can explain the question again, that'll probably help in finding a solution
Related
I have a combo box which I need to mirror in another tab page in a C# winforms based application.
I have perfectly working code for when you select a different item from the drop down list. Unfortunately, however, when I change the Text of a tab that has not been clicked on yet nothing actually happens.
If I first click each tab then everything works as expected.
Now I'm putting this down to some form of lack of initialisation happening first. So I've tried to select each tab in my constructor.
tabControlDataSource.SelectedIndex = 0;
tabControlDataSource.SelectedIndex = 1;
// etc
But this doesn't work.
I've also tried calling tabControlDataSource.SelectTab( 1 ) and still it doesn't work.
Does anyone know how I can force the tab to "initialise"?
Ok, typically I post the question after struggling for an hour and shortly afterwards find the solution.
TabPages are lazily initialised. So they don't fully initialise until they are made visible for the first time.
So i added this code to my constructor:
tabControlDataSource.TabPages[0].Show();
tabControlDataSource.TabPages[1].Show();
tabControlDataSource.TabPages[2].Show();
but this didn't work :(
It occurred to me, however, that the constructor might not be the best place. So I created an event handler for Shown as follows:
private void MainForm_Shown( object sender, EventArgs e )
{
tabControlDataSource.TabPages[0].Show();
tabControlDataSource.TabPages[1].Show();
tabControlDataSource.TabPages[2].Show();
}
And now everything is working!
Perhaps you could also use sort of a "lazy" synchronization (initialization) in this case. Quick robust ideas: polling timer to update content (which will update it once you see tab page), no dependses within second tab (no Changed events for combobox to update second tab content, use original combobox from first tab or rather have it's content underlying in accessable for both comboboxes class, etc), "reinitialization" when tab become visible (at which moment you also init your second combobox)...
Can't be a hour, no way =D
We display our data on datagrids, bound to a dataset, which is in turn fed from a Progress database on the server. During processing, we need to make a change to the data-set and refresh it's value from the server. So far, all well and good and no problems.
The problem is that when we come back with the new data, we want the selection in the datagrid to remain on the same row it was on before. We've managed this with the following code:
int iPostingPos = dgridPostings.CurrentRow.Index;
// process data on server
dataContTranMatch.RunBoProcedure(dataContTranMatch.BoProcedure,
transactionMatchingDataSet);
// Reload Data
LoadData();
if (iPostingPos > ttPOSTingsRowBindingSource.Count)
{
iPostingPos = ttPOSTingsRowBindingSource.Count;
}
if (ttPOSTingsRowBindingSource.Count > 0)
{
ttPOSTingsRowBindingSource.Position = iPostingPos;
dgridPostings.Rows[iPostingPos].Selected = true;
}
This works, but we get the selected line jumping about on the screen, which is really annoying the users.
For example, if you select row 7, then run this code, you have row 7 selected, selection then jumps to row 0, then jumps back to row 7. This isn't acceptable.
In an attempt to fix this, we've tried enclosing the above code in the following additional lines:
chTableLayoutPanel1.SuspendLayout();
*DO CODE*
chTableLayoutPanel1.ResumeLayout();
But this didn't help.
So far, the most acceptable solution that we've been able to reach is to change the colour on the selection so that you can't see it, letting it leap about and then putting the colours back as they should be. This makes the flicker more acceptable.
dgridPostings.RowsDefaultCellStyle.SelectionBackColor =
SystemColors.Window;
dgridPostings.RowsDefaultCellStyle.SelectionForeColor =
SystemColors.ControlText;
DO CODE
dgridPostings.RowsDefaultCellStyle.SelectionBackColor =
SystemColors.Highlight;
dgridPostings.RowsDefaultCellStyle.SelectionForeColor =
SystemColors.HighlightText;
We beleive that the issue is caused by the binding source being temporarily empty as the dataset is refreshed, we then re-navigate one it's got data in it again.
Can anyone offer any ideas on how we can prevent this unpleasent flicker from occuring?
Many thanks
Colin
It may be a bit heavy handed but one option would be to suspend painting of the control. A user asked how to achieve this here: How Do I Suspend Painting For a Control and Its' Children. I've used the selected answer there to achieve something similar.
It sounds stupid, but this happens to me.
I activate a function, and it does its work, and after it finishes it enables itself again. With other words, the function activates twice, not once. I tried to find out why by debugging, but I didn't find the reason.
When I click on a panel this function activates:
private void Play(object sender, EventArgs e)
{
Play0(MousePositionX, MousePositionY);
if (swich_player == true && AI_enabled == true)
{
AI_playing();
swich_player = false;
}
}
The whole code is really long.
Is it me not searching correctly? Are there other reasons? In order for this function to start again, something has to activate it. I can't find what is activating the function again.
Any suggestions, where to search for the problem? Or what is the problem?
EDIT:
I finally found the problem. There is a button (button1) that changes the panel's properties, and a second button (button2) that makes the panel 0 pixels wide and 0 pixels high (in order to make it invisible). The first button also adds an EventHandler that activates the function. But button2 does not remove the EventHandler. This way the function gets called as much times as the times I have pressed button1.
Looks like what you're looking for (via your comments/edit) is the source of multiple calls to this function. With the current snippet of code, it's not possible for us to tell. But what you should do is put a breakpoint on the entry of the function and then when it is hit, look at the "Call Stack" window in visual studio.
This can be accessed via the Debug -> Windows -> Call Stack menu item (when running the program. It will not show up in Windows if you're not running)
You can then see what is calling your function through this window. It is an extremely useful tool.
Pre Edit:
Your question isn't very clear, but I think (from your variable names) that you're looking for a game loop that will continually run. If so, take a look at this blog post which has some very good information on different styles of game loops. It ranges from simple to more complex (and scalable) loops.
Your question states that you activate something once and it "enables again", and also that "In order this function to start again, something has to activate it. I can't find what". These seem to be contradictory statements. Can you edit your question to be a little clearer? If my answer is not what you were looking for after your edit, I will do my best to add whatever is needful.
check against which event you've registered this function. if you registered into to something no "OnClick" of that button, it might be the root cause
I'm having a pretty nasty problem with an auto-completing textbox. I want to initiate an asynchronous PostBack whenever a user selects an item from the auto-completed field and retain the value of the item, rather than the text inputted. This works perfectly when enter is pressed rather than a mouse click.
An example of my issue:
Someone goes to the page, and types 1000 into the textbox. The autocomplete displays 10002, 1000B, and 10000. The user clicks on 1000B and an asynchronous PostBack initiates. Instead of 1000B, the TextBox.Text value is still 1000.
My assumption is that the textbox is initiating the PostBack before the value is actually getting assigned to it. I'm just curious if anyone has any possible solutions for what I'm talking about.
I fixed it in this manner:
As per another question on the site I added an autoPostBack parameter to the options list.
In bottom of the SelectCurrent() function, I added these lines.
if (options.autoPostBackSelection == true) {
__doPostBack($input.id, "");
}
Then, my blur function looked like this:
.blur(function() {
hasFocus = 0;
if (!config.mouseDownOnSelect) {
hideResults();
}
if (options.autoPostBackSelection == true) {
selectCurrent();
}
I actually struggled with this for a bit, my Javascript/DOM event skills aren't very good. Hopefully this helps someone.
When a winform first displays, the checkbox is unchecked by default. If when the form first displays, I click on the checkbox to 'check' it, the checkbox appears checked for a split second and then disappears. The checkedchanged event never fires. However, if anytime after the first initial attempt I click on the checkbox, the value changes (checked to unchecked and vice versa) like it should and the event fires.
Any idea why the checkbox would not check on the first attempt? It appears selected the first time when you hover over it so I know it has focus.
Update: it doesn't matter if you enter data into all other controls first and then click on the checkbox, the first time you click on it, it flashes as checked for a second, and then the check disappears. Anytime after the 1st time though it works. Strange...
Hard to tell without seeing a code snippet. When I've had things like this in the past, it's been due to having duplicate control ids, or wiring up event handlers incorrectly. Have you tried disabling portions of your code and seeing what affects the checkbox behaviour?
Strangely, putting code in the CheckedChanged() to set the value (what it gets set to anyway if I trace through it) seems to work:
if (this.chkbox1.Checked == true)
{
this.chkbox1.Value = "1";
this.chkbox1.Text = "Checked";
}
else
{
this.chkbox1.Value = "0";
this.chkbox1.Text = "Un-checked";
}
I also put a focus() in the click():
if (((System.Windows.Forms.MouseEventArgs)(e)).Clicks <= 1)
{
if (this.chkbox1.Focused == false)
{
this.chkbox1.Focus();
}
}
I have no idea why that fixes the problem, but it does.
do this happen with just one CB? or all the CB on the form.
Have you tried deleting the CB then adding it back?
I would suggest you post the code behind the CB?
For your custom code, I would try using different cast styles, to see if it makes any difference.
If you're using the standard C# syntax, and it fails (vanishing checkbox)
CheckBox checkBox = sender as CheckBox;
I would try using the old-style cast on the sender object and see if it gives you the desired result:
CheckBox checkBox = (CheckBox)sender;
This may give you a hint on the root cause.