How can I access my applications images that are in my resources? - c#

I'm going to briefly explain what I want my program to do.
I have a lot of Images on my form and I want the image source to change on MouseEnter event.
So, if a user moves the mouse over the button, I'd like the button to appear to be glowing. Of course I've made two images for the Image control. One normal, and one glowing. I'm trying to make a single event on mouseEnter for all of the images because I don't want to pollute my code with 60+ events all essentially doing the same thing.
Someone suggested I do something like this:
void HeroMouseEnter(object sender, EventArgs e)
{
((PictureBox)sender).Image = GetImage(((PictureBox)sender).Name)
}
Honestly, this would work exactly how I need it to. But I'm a bit confused is about the GetImage() method.
How exactly would I code this? All of my images, both the glowing and non glowing ones are already added to my resources. How would I summon them according to the PictureBox's name?
I tried making a dictionary with the key being the name of the pictureBox and the value being the resource file, but no dice.
Please help!

Something like this?
public Image GetImage(string name)
{
switch (name)
{
case "PictureBox1":
return Properties.Resources.Picture1;
case "PictureBox2":
return Properties.Resources.Picture2;
default:
return null;
}
}

Related

How to change the window size with each time in C#

Its that I am developing an application in C# and I have used three tab controls there. The problem is I can not change the actual window size of the application when I change to another tab because I do not need such big window for that and when I change back to the previous one it should go back to previous size.
In my opinion you should not change the size of the window when the selected tab changes. Design your window in such a way that you don't need to resize it.
Redesign your tabs in such a way that they always consume the same size so you don't need to resize the window.
I would not expect, as a user, that the window size changes because it may give you a bad user experience.
i think you want this:
private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
{
if (tabControl1.SelectedTab.Text == "tabPage1")
{
// rezise tabcontrol
}
}
although i dont think its user-friendly

How can I check if a PictureBox's image has been modified?

I'm working on a super top-secret application right now that has a PictureBox on it. There are some options to edit the image inside of the PictureBox, including (but not limited to) sepia, grayscale, and some rotations.
At the moment, however, there isn't any way to check if the image has been modified - as I've been trying to create a "Would you like you save your changes??!" dialog box, which would appear if the image has been modified in any way.
I've got all of the actual modifications set in stone at the moment - all I need is a reliable method of checking if the PictureBox's image has been modified.
mmm.. Every time the user use an option to edit the image, just set a flag to true. That way you know that the image has change.. in fact, you are changing it somehow, so you know when is modified!
Does the BackgroundImageChanged Event fire? Use that.
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.backgroundimagechanged.aspx
There are some options to edit the image inside of the PictureBox,
including (but not limited to) sepia, grayscale, and some rotations.
private bool isChanged = false;
void Apply_sepia() {
isChanged = true;
// apply sepia
}
void close(...) {
if(isChanged) {
if(MessageBox.Show("Are you sure?", SomethingOptions.YesNo) == MessageBoxOptions.Yes) {
Application.Exit();
}
} else {
Application.Exit();
}
}
I obviously cannot remember what the correct property names are.. however you get the gist.

How to detect previous state of text field in C#?

I'm coding a simple text editor using Windows Forms. As in many editors, when the text changes the title bar displays an asterisk next to the title, showing that there is unsaved work. When the user saves, this goes away.
However, there is a problem. This is handled in the change event of the main text box. But this gets called too when a file is opened or the user selects "New file", so that if you open the editor and then open a file, the program says that there are unsaved changes. What is a possible solution?
I thought of having a global variable that says whether the text changed in a way that shouldn't trigger the asterisk, but there has to be a better way.
before loading data to a textbox, unassociate first the eventhandler for change
uxName.TextChanged -= uxName_TextChanged;
uxName.Text = File.ReadAllText("something.txt");
uxName.TextChanged += uxName_TextChanged;
This is a horrible solution, but every time the text change event fires, compare the value of the textbox to some variable, and if they are different store the contents on the textbox in a variable and add the asterisk. When the method is invoked via the New File dialog or any other such event that is NOT changing the text, the asterisk won't appear.
This is not a viable solution for a real text editor since the memory would quickly get out of hand on even medium-sized files. Using a finger tree or whatever data structure text editors use to compare "versions" of the text is the only real efficient solution, but the premise is the same.
http://scienceblogs.com/goodmath/2009/05/finally_finger_trees.php
Below the second picture he mentions the use of finger trees in text editors to implement an extremely cheap "undo" feature, but I'm sure you can see the validity of the tree for your problem as well.
There are no global variables in C#. You should have such an variable as an instance variable in your form (or better yet, in a model for which your form is a view), and that is perfectly fine.
This is a very simple and stupid solution. I would use a MVP design pattern for this but here the fastest and simple solution:
//Declare a flag to block the processing of your event
private bool isEventBlocked = false;
private void OnTextChanged(object sender, EventArgs e)
{
if(!isEventBlocked)
{
//do your stuff
}
}
private void OnNewFile() //OR OnOpenFile()
{
try
{
isEventBlocked = true;
CreateFile();
}
catch
{
//manage exception
}
finally
{
isEventBlocked = false;
}
}

How to inherit base Textbox to provide colored borders

I have a winform app that we use in house. It has many individual controls on each of it's 25 "pages"(usercontrols). Our user base prefers very technicolor apps...they want a TextBox to be outlined Blue if it is a required field (color should go away if data entered). They want a TextBox to change to outlined Green if data has been changed in it to remind them to save. They want a currently highlighted TextBox to be outlined RedOrange.
I have been trying to come at this from many different angles (some of you have probably seen similar posts by me lately). Non of them work... So one way I KNOW will work is to register the paint event for every control and check for a "required" tag for the required portion. The OnFocus for the current field portion and finally the Validate event for the data changed portion.
I know this is not the best way or at least I STRONGLY suspect it isn't but I am out of time, nearly, and nearing my point of frustration. That being said, will that DESTROY my app's responsiveness? Is there a better way? Can I override the base control to color on different premises so that I don't have to go to each of the 100+ controls?
Any idea would be welcome because I am between my stupid Paint_Event idea and rewriting all the controls in WPF... :)
I will be rewarding a solution that works for me and that I can implement shortly with a Bounty.
I am so sick of colors...
Here is my attempt based on suggestions.
public class MyTextBox : TextBox
{
private bool _isRequired;
public bool isRequired
{
get
{
return _isRequired;
}
set
{
_isRequired = value;
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (isRequired && base.Text.Equals(string.Empty))
{
HighlightControl(e.Graphics);
}
}
private void HighlightControl(Graphics graphics)
{
ControlPaint.DrawBorder(
graphics,
this.ClientRectangle,
Properties.Settings.Default.RequiredFieldColor,
Properties.Settings.Default.BorderWidth,
Properties.Settings.Default.BorderStyle,
Properties.Settings.Default.RequiredFieldColor,
Properties.Settings.Default.BorderWidth,
Properties.Settings.Default.BorderStyle,
Properties.Settings.Default.RequiredFieldColor,
Properties.Settings.Default.BorderWidth,
Properties.Settings.Default.BorderStyle,
Properties.Settings.Default.RequiredFieldColor,
Properties.Settings.Default.BorderWidth,
Properties.Settings.Default.BorderStyle);
}
}
I don't know the particulars of your app, but you could derive your own control from the base TextBox and let it handle much of this for you. Some thoughts:
Give it a bool Required property and some internal logic to color accordingly.
Have the textbox respond to its own
events - when text is entered, it can
do the right thing - change colors or
whatever is appropriate.
Provide your derived control with
properties to set the colors that get
used for each condition, then you can
switch them easily when the users
decide they want pink rather than
green.
You can utilize the focus events to "know" whether your TextBox (this is the one control you mentioned, so I'll assume this is the main control used here) has focus or lost it and the text change events can be used to drive all the color changes to the control.
You can certainly wire up all the
text boxes to control the
Apply/OK/whatever buttons to
determine if the buttons should be
enabled, assuming you have an Apply button or something like that which stores the data on click. There are a number of ways to communicate this. It's easy enough to iterate through the controls and ask their state.
Seems like this would work just fine.
What have you tried? You didn't really mention what you'd tried that didn't work.
You've got a problem, TextBox is, erm, special. Windows Forms leaves all painting to the native Windows EDITBOX control, the Paint event won't be raised. That can be fixed by setting the UserPaint control style to true:
using System;
using System.Drawing;
using System.Windows.Forms;
class MyTextBox : TextBox {
public MyTextBox() {
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
// Paint something
//...
}
}
Copy and paste this into a new class, compile and drop the new control from the top of the toolbox. Try it out, you'll be quite disappointed. What you see is the result of close to 20 years of appcompat hacks on a control that dates back to Windows version 2. One of the grave crimes that EDITBOX commits is painting itself without generating a WM_PAINT message. That was important way back when Windows had to run on a 386SUX, keeping it compatible with old programs prevented Microsoft from fixing its behavior.
No happy answers here, you'll have to give up on the idea of customizing the border. What you can do is give the control a distinct BackColor when it has the focus. For example:
class MyTextBox : TextBox {
Color mBackColor;
protected override void OnEnter(EventArgs e) {
mBackColor = base.BackColor;
base.BackColor = Color.AliceBlue;
base.OnEnter(e);
}
protected override void OnLeave(EventArgs e) {
base.BackColor = mBackColor;
base.OnLeave(e);
}
}
You can inherit from base control classes and add your own drawing logic. That won't be very expensive performance-wise, but, if your app is of significant size, you'll have to replace each occurence of standard TextBox with your own implementation.

Cycle Button Background Images in C#

I have a form in C# that has a button that, when clicked, I want the background image to cycle through a set of images (which I have as resources to the project). The images are named '_1', '_2', etc. and each time I click the button I want its background image to increment to the next one and go back to "_1" when it gets to the highest. Is there a way to do this?
I tried getting button1.BackgroundImage.ToString() but that yields System.Drawing.Bitmap instead of Resources._1 like I was thinking it would (in which case I could just get the last character and switch on that to change the background to the appropriate new image).
Thanks for your help.
Why don't you just put the images in an array?
You could subclass Button and override the BackgroundImage property so you can better keep track of the current resource that represents the image. You might also override the onclick method to internally handle cycling to the next image, though that might be a little weird if the resources are handled outside of your derived button class.
class YourClass
{
private IEnumerator<Image> enumerator;
YourClass(IEnumerable<Image> images)
{
enumerator = (from i in Enumerable.Range(0, int.Max)
from image in images
select image).GetEnumerator();
enumerator.MoveNext();
}
public Image CurrentImage { get { return enumerator.Current; } }
public void OnButtonClick() { enumerator.MoveNext(); }
}
You can use this code as a backing class for your control under the assumption that user wont click the button more than two billion times.
Just note that once this class is created you cannot modify given image list outside. If you want to do such things you need to implement disposable pattern and dispose the enumerator accordingly.

Categories