I want to change the BackgroundImage of a button when you click once, and then change it back to the original when clicked again (and it will work over and over). My code snippet is this:
private void handButton_Click(object sender, EventArgs e)
{
if (handButton.BackgroundImage == WindowsFormsApplication1.Properties.Resources.Hands_Right)
{
handButton.BackgroundImage = WindowsFormsApplication1.Properties.Resources.Hands_Left;
}
else if (handButton.BackgroundImage == WindowsFormsApplication1.Properties.Resources.Hands_Left)
{
handButton.BackgroundImage = WindowsFormsApplication1.Properties.Resources.Hands_Right;
}
}
But when I run the program and click the button; nothing happens. The images are 32x32, and I can see the original image clearly. When clicked, the original image stays there. There are no other variables affecting this snippet (at least, a search for "handButton" only gets results from this snippet).
Any suggestions? I have no errors, so I suspect that I'm going about this wrong. Is there a better way to change images back and forth?
The Properties.Resources class doesn't work the way you think. A property like Hands_Right actually returns a new bitmap, not whatever object was returned previously. That wouldn't work very well since modifying the bitmap would also modify the property from its design.
So your if() statement expressions never evaluate to true. Keep track of the button state separately.
Related
As you can see below, save code.
No errors at all.
Image
But when I change the state of the checkbox and close the form, the setting does not update and remains false.
Yes I do have something that uses the setting, and that works normally.
I am not following what the problem is. How are you “checking” if the setting is saved? In other words, I see nothing in your current code that actually USES the setting. I suggest you grab and apply the Properties CheckBox setting value to the CheckBox ExampleToggle when the form loads. Something like…
private void Form1_Load(object sender, EventArgs e) {
ExampleToggle.Checked = Properties.Settings.Default.CheckBox;
}
Also, in the future, posting pictures of code is frowned upon. You are forcing others who may help you into typing the code themselves. Many will just move on if they have to type the code.
I have a custom WPF control that inherits from RichTextBox. I'd like to be able to modify the FlowDocument of the richtextbox whenever the text is changed. For demonstration, let's say that we have this:
<MyCustomRichTextbox>
<FlowDocument>
<Paragraph>This is the first paragraph</Paragraph>
<Paragraph>And this is the second</Paragraph>
</FlowDocument>
</MyCustomRichTextbox>
and whenever the text is changed (e.g. someone types in the control), the entire containing paragraph is colored red.
It seems to me that two things need to happen in order to achieve this:
I need to somehow get the block that contains the changed text out of MyCustomRichTextbox.Document.Blocks
I need to modify that block
Unfortunately, the OnTextChanged method doesn't provide a way to get the Block that changed. I was able to use LINQ and the TextChangedEventArgs.Offset to get the block, but I'm concerned that this approach will yield unacceptable slowdowns with larger documents (since it must enumerate each block every time a character is typed). Is there a better way to get the containing paragraph?
I know I could cache a reference to the "Last modified block" and check if it's still the one being modified, but that wouldn't really help in a random access scenario.
If I understand your problem correctly, you want to highlight the containing Paragraph of the current selection (the current position of the caret). So it's obviously that you have to get the containing Paragraph each time the Selection changes. Then you can just change the Foreground to Brushes.Red. Fortunately that the containing Paragraph seems to be referenced by the TextPointer and the process of finding it is nearly immediate. (a TextPointer has a property called Paragraph). Here is the detailed code:
Paragraph p = null;
//Suppose rtb is the name of your RichtTextBox
private void UpdateContainingBlockState() {
if (p != rtb.Selection.Start.Paragraph){
if (p != null) p.Foreground = Brushes.Black;
p = rtb.Selection.Start.Paragraph;
if (p != null) p.Foreground = Brushes.Red;
}
}
//The SelectionChanged event handler for your RichTextBox
private void selectionChangedHandler(object sender, RoutedEventArgs e){
UpdateContainingBlockState();
}
The frequency of changing the Selection is fairly high (each time you press almost keys which can cause the selection changing). So if your document is large and you realize some poor performance while typing, it's time to switch to the next more complex code. You can also try using Threading approach (or using Task) to put the UpdateContainingBlockState() call in another thread but be careful about cross-thread access. Here I use a different approach, the idea is call the UpdateContainingBlockState() at the right time, that is when the actual selection change can jump between paragraphs. While typing normal printable characters, the selection will be always in the current paragraph (so we don't need to call UpdateContainingBlockState()) unless when you type the Enter key. Generally we will call the method when user typing a control key (arrow keys, home, end, Enter, ...). We should also call the method if the RichTextBox gets focused and if user clicks mouse on the RichTextBox. You can see that almost the typed characters won't trigger calling the method so it will improve the performance much more than the code above (of course it may be realizable only when the document is large). Here is the detailed code:
//should add this using at the beginning
using System.Runtime.InteropServices;
[DllImport("user32")]
private static extern int MapVirtualKey(int ucode, int mapType);
//The KeyUp event handler for your RichTextBox
private void keyUp_Handler(object sender, KeyEventArgs e){
if (char.IsControl((char) MapVirtualKey(KeyInterop.VirtualKeyFromKey(e.Key),0x2)))
UpdateContainingBlockState();
}
//The PreviewMouseUp event handler for your RichTextBox
private void previewMouseUp_Handler(object sender, MouseButtonEventArgs e){
//UpdateContainingBlockState();
//Calling UpdateContainingBlockState() directly will cause a small issue
//So we use this instead
Task.Run(() => Dispatcher.Invoke( () => UpdateContainingBlockState()));
}
//The GotKeyboardFocus event handler for your RichTextBox
private void gotKeyboardFocus_Handler(object sender,
KeyboardFocusChangedEventArgs e){
UpdateContainingBlockState();
}
I have an AutoCompleteBox binded to an ObservableCollection ItemsSource which I filter on my own by querying entities from a domainservice.
I used the scenario of populating from a webservice call from the blog of Jeff Wilcox, by setting the PopulatingEventArgs.Cancel to True, and when my collection is ready, I call PopulateComplete() on the ACB.
My goal is to reopen the dropdown on mouseover (or click) but without reloading again all the data from the web. I found a question on stackoverflow where the answer was to set IsDropDownOpen to True. But in this case, the ACB population starts again, and another call goes to the webservice.
Of course, when the user starts typing, the filtering should be done again.
(for ex. you type "ric" and the box suggests "rice" and "ricin", you select rice, but you change your mind and want to select another one from the same collection, lets say "ricin". In this case you already have the suggestions containing "ric" in memory, no need to load them again..)
I found an alternative way in which instead of setting IsDropDownOpen, I just simply call the PopulateComplete() method. This does exactly the same thing that I want, but with a little fail: after my ACB loses focus, the dropdown is not opened again on mouseover liek it should. Even when I click back into the acb textbox.
So is there a fix for this, or does someone know why the PopulateComplete() only reopens the dropdown when the ACB has focus for the first time? Or this was only my luck that calling this method reopened the dropdown and the IsDropDownOpen property should be used instead (afaik this would be only possible with some flags indicating that its a fake populating event triggered by my mouseover and after PopulatingEventArgs.Cancel i should call immediately PopulateComplete. but i dont get it, if this may work (haven't tried yet), why not when calling simply the PopulateComplete)?
Well, I tried the IsDropDownOpen with a testing bit, and almost worked:
private void FoodBox_MouseEnter(object sender, MouseEventArgs e)
{
//FoodBox.PopulateComplete(); not working after acb loses focus...
testbit = true;
FoodBox.IsDropDownOpen = true;
}
Here's the overloaded Populating method (no need for setting ItemsSource explicit because its bound to an ObservableCollection):
public void FoodBox_Populating(object sender, PopulatingEventArgs e)
{
e.Cancel = true;
if (!testbit)
{
VM.LoadFoodSuggestions(FoodBox.SearchText);
}
else
{
testbit = false;
FoodBox.PopulateComplete();
}
}
This works good so far, execpt that the search does not start because when (for the first time) you mouseover and select the acb, it sets the testbit to true.
So I added another event handler that takes care of setting the testbit to false every time the user inputs text on the keyboard, ensuring that the suggestions are regenerated/reloaded after SearchText is modified by the user, but not when you select an item from the dropdown:
private void FoodBox_TextChanged(object sender, RoutedEventArgs e)
{
testbit = false;
}
I still don't know why calling PopulateComplete() isn't enough without setting the IsDropDownOpen to Ture, and setting that to true, also delays the dropdown opening approximately with the time specified in the MinimumPopulateDelay, but at least it gives me the functionality I wanted. (Maybe digging into the source of acb would answer this mistery)
Maybe this functionality implemented in the basic acb would be helpful in a future release of the control.
I'm attempting to use the ScintillaNET control in an application I am working on. I drag and drop the control into my form and run form. The control appears on the form. This is good. In addition, if I set any of the properties in the control's properties editor (ConfigurationManager.Language, for example), I am able to type in that language and see syntax highlighting occur.
Where I run into problems is when I attempt to change properties programmatically. For example, I attempt to load text from a file into the form (I'm doing this in the form's Load). The text doesn't display. I also can't seem to show the line numbers or do any other number of tasks (including programmatically change the Language).
Any idea what I may be doing wrong? Even something as simple as the code below doesn't seem to work:
private void scintilla1_Load(object sender, EventArgs e)
{
scintilla1.ConfigurationManager.Language = "xml";
}
Simply add scintilla1.ConfigurationManager.Configure();
private void scintilla1_Load(object sender, EventArgs e)
{
scintilla1.ConfigurationManager.Language = "xml";
scintilla1.ConfigurationManager.Configure();
}
After spending some time playing around with the different events, it appears that I cannot affect the Scintilla control until after it is already visible. Hence, the "Load" event does not let me make any programmatic changes to the control until I've set it visible.
It's a little strange, and seems sort of pointless to me to have the Load event at all, but I just wanted to let everybody know what is happening in case someone else ran into the same problem.
Simplifying
I have a text box and a button
The button just create an messagebox with the text from the textbox.
But i change the value of the textbox, the new value apears (Ex: Type 123) but the message box does not show the value.
If i try to use the value in the programming (get the value by textbox1.text) the variable has nothing ( textbox1.text = "") but i can still see what i typed in the form.
Anyone has any clue?
Your button's click event handler should look something like this
private void button_Click(object sender, EventArgs e)
{
MessageBox.Show(textBox.Text);
}
I suspect you already have code similar to this and that at some point the textbox is cleared or otherwise set to String.Emppty but without seeing actual code it is difficult to help you
When/where did you check the value of textBox1.Text? If you're checking it in the constructor, Form1_Load, or anything else that occurs before you'll have typed text, you will get an empty value.
To properly check the value of textBox1.Text, you should set what's called a breakpoint on the line that calls MessageBox.Show(textBox1.Text). To do this, click in the grey area of the source editor (it's on the far left) on the line containing MessageBox.Show(..). A red circle will appear and your code should be highlighted. When you run your application and click on your button, your application should pause and Visual Studio will highlight that line and from here you can hover over "textBox1.Text" in the MessageBox.Show() line and it should show you the current value.
If your application is as simple as a form, a textbox, and your button1_Clicked event handling code, this should work no problem. If it is not this simple, then you need to look for anything that sets the value of the textBox in your code and make sure it isn't passing any blank values by using breakpoints.
To solve this properly, though, we really need more information.
Thanks Eric and Crippledsmurf. As both of you said, its hard to help without the code.
The problem I found is that when calling the form, I send some objects by reference, so I can track them down and I found that when (don't ask me why it happens that way, I'm still working on it) the construtor is called he make an new component, so the component in the interface no longer represents the one pointed by the variable "textbox1" (Yes Crash893, I haven't mispelled the name).
I found that I was making some mess with the references, and probably that was causing the problem. I fixed the problem by changing the actions performed by references for delegates and events, but I couldn't track down the exactly source of the problem.
Thanks, again, everyone for the insights.