Combobox how to get the selected item to show a theme - c#

I'm doing a tic tac toe game and I am trying to add a combo box that will change the applications background based on what the person selects right now I have summer, spring, fall, winter and the images are in the bin/debug folder how can I get this to work I don't know where to start and the tutorials are a bit confusing. Could you please help me

It isn't exactly clear what you are asking. Assuming you've got bitmap files with names like "spring.png" etc in your bin\Debug folder, this ought to work:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
comboBox1.Items.AddRange(new string[] { "Spring", "Summer", "Fall", "Winter" });
comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged;
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
string folder = Application.StartupPath;
string theme = (string)comboBox1.Items[comboBox1.SelectedIndex];
string path = System.IO.Path.Combine(folder, theme + ".png");
Image newImage = new Bitmap(path);
if (this.BackgroundImage != null) this.BackgroundImage.Dispose();
this.BackgroundImage = newImage;
}
}

There are many ways to do this. This is probably the simplest:
Set your main form's BackgroundImageLayout to Stretch.
Place 4 PictureBox controls on your form, and set their Visible properties to false. Name them pbWinter, pbSpring etc. Set the Image property of each by browsing to the image file for each season.
Add a ComboBox to your form. Add the items "Winter", "Spring", "Summer" and "Fall".
In the combo box's SelectedIndexChanged event handler, check the box's Text property with a switch statement, and set the appropriate back image with code like this:
this.BackgroundImage = pbWinter.Image; // etc. ...
Update: Here's how to do the switch statement:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
switch (comboBox1.Text)
{
case "Winter":
this.BackgroundImage = pbWinter.Image;
break;
case "Spring":
this.BackgroundImage = pbSpring.Image;
break;
// etc...
}
}

Related

Changing a color of a icon from an action on an other page

I am a beginner on C#, I am coding an UWP app on Visual Studio, mostly for Windows 10 platforms.
Here's my problem:
I have a navigation view on the main page, which lists a few subjects.
Clicking on one of them brings you to a page (Page1) where I have radio buttons, that changes the color of the title of this Page1.
I would like to have this color applied to the subject on the main page
Can't figure out how to do...
Any tips?
Thanks!
You can access the NavigationView in MainPage.xaml.cs by creating a static instance of MainPage and change the color.
Here is the solution:
MainPage.xaml
<NavigationView x:Name="nvSample"
x:FieldModifier="Public">
...
</NavigationView>
MainPage.xaml.cs
public static MainPage Current;
public MainPage()
{
this.InitializeComponent();
Current = this;
}
Page1.xaml.cs
private void RadioButton_Checked(object sender, RoutedEventArgs e)
{
var nav = MainPage.Current.nvSample;
nav.Foreground = new SolidColorBrush(Colors.Yellow);
}
Best regards.
Thank you very much Richard, I made it :)
The Page1.xaml.cs code changed all the texts foreground in my page though, so I used this:
private void RadioButton_Checked(object sender, RoutedEventArgs e)
{
RadioButton radio = (RadioButton)sender;
{}
if (radio != null)
{
String selected = radio.Tag.ToString();
switch (selected)
{
default:
case "Red":
Title.Foreground = new SolidColorBrush(Colors.Red);
MainPage.Current.Subject1.Foreground = new SolidColorBrush(Colors.Red);
break;`
Thank you again.
Now next mission for me, saving those colors after the application is closed so they stay the same when the app is lunched. If you have any advices... :)

Using xaml states to change window size programatically

I have created 2 states for the main window of the program (big and small) and i have added a tabcontrol with 2 tab items. I want to use the big state to change the size of the window when i am in tab1 and small state to change the size of window when i am in tab2. I used the following code but an unable to change the window size.
private void Changes(object sender, SelectionChangedEventArgs e)
{
if (tab1.IsSelected)
{
VisualStateManager.GoToElementState(window, "Big", true);
b1.Text = Convert.ToString(i);
}
else
{
VisualStateManager.GoToElementState(window, "Small", true);
b1.Text = Convert.ToString(i);
}
}
the method Changes is the tabcontrol's SelectionChanged event.
I cannot find what i did wrong here.

Reference and store Data from Dynamically created Controls?

I have a problem I've been looking into for a few days now, I just can't think of a logical way of doing what I want.
I have an app which has a task list. It starts of with 3 controls: a textbox, datetimepicker and a PictureBox which changes image on click. The user can then press an image which will add another row of controls below (It gets the properties of the dynamic controls from the controls already created):
https://www.dropbox.com/s/o2pub6orww24w25/tasklist.png (This is a screenshot to make it clearer)
Now what I want to do is save the values from each of the rows (A row being defined as: Textbox, Date, Status) into an SQLite DB.
For the first row it is easy, because that has a unique design name (and is a 'static' control).
However, the problem hits when I attempt to save values from the dynamic controls:
Problem a) I cannot reference the dynamic control because 'It does not Exist in the current Context'. -The function for creating the controls has a public access modifier so I thought that should do the trick? -It didn't. I've also tried:Panel1.pb.blah but it still didn't recognize the control?
Problem b) How can I tell my program that each row is a new set of data? In other words, how can I run a new insert command for each row? -I thought of doing this as a for-each-textbox loop, however would that not just pick up the first dynamic date everytime?
I've also thought of using the tag property and setting it to the counter variable, to group the controls in the row. (The counter being an integer which increments every time a new row is added.) However I cannot do that because the picture box uses the tag property as part of its function to change image on click (Changes multiple times).
Code:
Adding the Controls:
public void pictureBox1_Click(object sender, EventArgs e)
{
//TextBox Control
int tbh = tasktb.Location.Y + (counter*25);
int tbsh = tasktb.Size.Height;
int tbsw = tasktb.Size.Width;
TextBox tb = new TextBox();
tb.Location = new Point(9, tbh);
tb.Size = new System.Drawing.Size(tbsw, tbsh);
tb.Tag = counter.ToString();
//Date Time Control
int dth = duedatedb.Location.Y + (counter * 25);
int dtsh = duedatedb.Size.Height;
int dtsw = duedatedb.Size.Width;
DateTimePicker dtp = new DateTimePicker();
dtp.Location = new Point(300, dth);
dtp.Size = new Size(dtsw, dtsh);
dtp.Format = System.Windows.Forms.DateTimePickerFormat.Short;
//Picture Box Control
int stsh = status.Location.Y + (counter * 25);
int stssh = status.Size.Height;
int stssw = status.Size.Width;
PictureBox pb = new PictureBox();
pb.Location = new Point(429, stsh);
pb.Size = new Size(stssw, stssh);
pb.Image = Red;
pb.Click += new System.EventHandler(pb_Click);
panel1.Controls.Add(tb);
panel1.Controls.Add(dtp);
panel1.Controls.Add(pb);
++counter;
}
Trying to Reference the control: (For purposes of changing the image on click) [Found the Control.Find function from researching this in the MSDN Website]
public void pb_Click(object sender, EventArgs e)
{
PictureBox pb = (panel1.Controls.Find("pb",false));
if (pb.Image == Red) { pb.Image = Orange; status.Tag = "Orange"; }
else if (pb.Image == Orange) { pb.Image = green; status.Tag = "Green"; }
else if (pb.Image == green) { pb.Image = Red; status.Tag = "Red"; }
}
The essential problem here is Problem a, if you guys could see where I have gone wrong with that, I'd be able to go away and attempt to write some code to get around problem b.
(I have included Problem b in this for your suggestions on the best way to do this. -At the moment I have no clue!)
Thank you for any help received! It really is appreciated!
ControlCollection.Find looks for a control with the specified name, and you haven't set any. The variable names in your code aren't related. So, either:
pb.Name = "pb";
But that would mean you'd eventually have several items with the same name. So, seeing how you want to change the picture of the clicked PictureBox, just do this:
public void pb_Click(object sender, EventArgs e)
{
PictureBox pb = (PictureBox)sender;
if (pb.Image == Red) { pb.Image = Orange; status.Tag = "Orange"; }
else if (pb.Image == Orange) { pb.Image = green; status.Tag = "Green"; }
else if (pb.Image == green) { pb.Image = Red; status.Tag = "Red"; }
}
The sender argument always contains a reference to whichever control raised the event, in this case whichever picturebox was clicked!
Edit: As for your other question, I assume you'll need to do stuff to the controls later on, so I suggest you store a reference to all of them (or at least the ones you need), something like this:
// helper class
private class Entry
{
public TextBox TextBox { get; private set; }
public DateTimePicker DateTimePicker { get; private set; }
public PictureBox PictureBox { get; private set; }
public Entry( TextBox tb, DateTimePicker dtp, PictureBox pb )
{
this.TextBox = tb;
this.DateTimePicker = dtp;
this.PictureBox = pb;
}
}
// member field
private List<Entry> m_Entries = new List<Entry>();
// at the end of pictureBox1_Click
public void pictureBox1_Click(object sender, EventArgs e)
{
....
m_Entries.Add( new Entry( tb, dtp, pb ) );
}
Then you can use the items in that list to interact with your rows. You might also want to add an index, or a reference to whatever the original data structure is. Also, you might want to think about if you really should be creating the controls yourself like that or actually use some kind of table/grid control to host them!
Or perhaps just wrap up all those controls in a single UserControl, with logic included and all!

ListView does not show images after switching view mode

When I add item(s) to the ListView in any other than LargeIcon view mode, the ListView stops showing the images from LargeImageList when it is switched back to LargeIcon. This situation lasts until new item is added to the ListView in the LargeIcon mode.
So the following sequence illustrates the problem:
create ListView, add column, set View to Details
create ImageList, set ImageSize, assign it to ListView.LargeImageList
create new ListViewItem, set its ImageKey
create new image, add it to the ImageList with given key
add the ListViewItem to the ListView
switch the ListView mode to LargeIcon
no images are shown
repeat steps #3 - #6, now in the LargeIcon mode
all images are shown as expected
What is the point I am still missing?
I have tried following:
Invalidate the ListView
Re-assign the LargeImageList before/after adding the item (even through null)
The test code for those who like it more than words:
public partial class Form1 : Form
{
int counter = 0;
ImageList iList = new ImageList();
private string GetNewKey()
{
return counter++.ToString();
}
private Image GetNewImage(Size size)
{
var bmp = new Bitmap(size.Width, size.Height);
using (var gra = Graphics.FromImage(bmp))
{
var rnd = new Random();
var lines = rnd.Next(1000);
for (int l = 0; l < lines; ++l)
{
var pen = new Pen(Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256)));
var p1 = new Point(rnd.Next(size.Width), rnd.Next(size.Height));
var p2 = new Point(rnd.Next(size.Width), rnd.Next(size.Height));
gra.DrawLine(pen, p1, p2);
}
}
return bmp;
}
public Form1()
{
InitializeComponent();
iList.ImageSize = new Size(100, 100);
listView.LargeImageList = iList;
listView.Columns.Add("name");
}
private void buttonAdd_Click(object sender, EventArgs e)
{
var key = GetNewKey();
var lvi = new ListViewItem()
{
Name = key,
Text = "blabla",
ImageKey = key,
};
iList.Images.Add(key, GetNewImage(new Size(100, 100)));
listView.Items.Add(lvi);
}
private void buttonClear_Click(object sender, EventArgs e)
{
listView.Items.Clear();
}
private void buttonLarge_Click(object sender, EventArgs e)
{
listView.View = View.LargeIcon;
}
private void buttonDetails_Click(object sender, EventArgs e)
{
listView.View = View.Details;
}
}
EDIT:
For anyone who would suffer the same problem. After some experiments, there is at least stupid poor man's workaround:
Modify the ImageList, the ListView somehow detects its change and reloads the images for LargeIcon mode. The questions are how it detects the change and why does it ignore the ImageList after mode change...
private void FixIt()
{
// Trigger a reload of the ListView.LargeImageList
if (listView.View == View.LargeIcon)
{
var key = "Dummy image to be deleted right after its insertion...";
iList.Images.Add(key, new Bitmap(1, 1));
iList.Images.RemoveByKey(key);
}
}
EDIT #2:
I have also discovered some other funny features the ListView and associated components have. You might want to check them in answers of question 4097912 and question 23059678
To solve your problem
You could avoid this by useing ImageIndex instead of ImageKey to connect your ListView with the ImageList. So in your buttonAdd_Click event use:
var lvi = new ListViewItem()
{
Name = key,
Text = "blabla",
//ImageKey = key,
//Use ImageIndex and don't set both
ImageIndex= Convert.ToInt32(key) //you could just use count++
};
The reason behind this problem:
The reason behind this is not clear to me, but I assume this may be a bug that when changing from Details to LargeIcon, it only checks ImageIndex in default and if you set ImageKey the ImageIndex will be set to -1. Or may be this is by design, I don't know (see ImageKey section below), since you don't have a SmallImageList, so when changing to LargeIcon view, ImageIndex is null or -1 and the ImageKey is ignored.
About ListViewItem.ImageIndex Property
The ImageKey and ImageIndex properties are mutually exclusive, meaning if one is set, the other is ignored. Furthermore, if you set the ImageKey property, the ImageIndex property is automatically set to -1. Alternatively, if you set the ImageIndex property, the ImageKey is automatically set to an empty string ("").
About ListViewItem.ImageKey Property
If you are using multiple image lists, for small and large icon view, with a ListView control, you should place small and large versions of the image at the same index location in their respective image lists. When switching between views, the index location of the image in one list is used to locate the image in the other list, regardless of the key value specified.
And this can somehow be verified:
using your existing code (use ImageKey)
set ImageIndex for any Item in your listView within the buttonLarge_Click event handler will show you that item's image.
set ImageKey for any Item within the buttonLarge_Click event handler will not show that itme's image.
e.g.:
private void buttonLarge_Click(object sender, EventArgs e)
{
listView.View = View.LargeIcon;
//Set ImageIndex of Item 0 you could see its Icon.
listView.Items[0].ImageIndex= 0 ;
//set ImageKey will change nothing
//listView.Items[0].ImageKey= "0" ;
}

Making text popup in a C# forms application on mouseover [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
create custom tooltip C#
Does anyone know of a way to make a box 'popup' when the user cursors over a certain item?
For example, I want to have a PictureBox on a C# forms application and when the user cursors over it, a box of text will pop up.
I'm aware of ToolTip however I was thinking of something more customisable; in my mind I'm thinking of the kind of popup boxes you see in World of WarCraft when you cursor over an item in your inventory (obviously it doesn't have to be THAT flashy, but at least one where the text colour, background colour, text etc. are all modifiable).
You can use a ToolStripControlHost to host a control (for instance a panel) and add the content you want. Then you add that control to a ToolStripDropDown using the Items collection, and use the Show(Control,Point) method to show the control.
Thought I'd add an example
public class Form1 {
public Form1() {
ToolStripDropDown customToolTip = new ToolStripDropDown();
customToolTip.Items.Add(new CustomPopupControl("Hello", "world"));
MouseMove += (o, e) => {
Point location = e.Location;
location.Offset(0, 16);
customToolTip.Show(this, location);
};
}
class CustomPopupControl : ToolStripControlHost {
public CustomPopupControl(string title, string message)
: base(new Panel()) {
Label titleLabel = new Label();
titleLabel.BackColor = SystemColors.Control;
titleLabel.Text = title;
titleLabel.Dock = DockStyle.Top;
Label messageLabel = new Label();
messageLabel.BackColor = SystemColors.ControlLightLight;
messageLabel.Text = message;
messageLabel.Dock = DockStyle.Fill;
Control.MinimumSize = new Size(90, 64);
Control.Controls.Add(messageLabel);
Control.Controls.Add(titleLabel);
}
}
}
I mean if it a button or an image button you can add something like MouseHover action and then show your message
private void button1_MouseHover(object sender, System.EventArgs e)
{
MessageBox.Show("yourmessage");
}
you need to customize the tooltip. refer to
http://www.codeproject.com/Articles/98967/A-ToolTip-with-Title-Multiline-Contents-and-Image
There are some other articles there, but this one works fine for me.
You may need to add code for your requirement.

Categories

Resources