When I am making a lot of buttons, is this the best way, or is there a better way? This code feels sort of clunky.
Button button = new Button();
button.MouseEnter += Button_MouseEnter;
button.MouseLeave += Button_MouseLeave;
Button button2 = new Button();
button2.MouseEnter += Button2_MouseEnter;
button2.MouseLeave += Button2_MouseLeave;
void Button_MouseEnter(object sender, EventArgs e)
{
BackgroundImage = Image.FromFile("buttonHover");
}
void Button_MouseLeave(object sender, EventArgs e)
{
BackgroundImage = Image.FromFile("button");
}
void Button2_MouseEnter(object sender, EventArgs e)
{
BackgroundImage = Image.FromFile("button2Hover");
}
void Button2_MouseLeave(object sender, EventArgs e)
{
BackgroundImage = Image.FromFile("button2");
}
I think there isn't better way. I would create a custom control with properties "button" and "buttonHover".
Something like this (not tested yet):
public class MyBytton : Button
{
public Image MainImage { get; set; }
public Image HoverImage { get; set; }
protected override void OnMouseEnter (EventArgs e)
{
if (HoverImage != null)
{
this.BackgroundImage = HoverImage;
}
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(EventArgs e)
{
if (MainImage != null)
{
this.BackgroundImage = MainImage;
}
base.OnMouseLeave(e);
}
}
Use:
MyBytton my = new MyBytton();
my.Location = new Point(10, 10); ;
my.Name = "button1";
my.Size = new System.Drawing.Size(141, 61);
my.TabIndex = 0;
my.Text = "test";
my.UseVisualStyleBackColor = true;
my.BackgroundImage = Image.FromFile("img1.jpg");
my.MainImage = Image.FromFile("img1.jpg");
my.HoverImage = Image.FromFile("img2.jpg");
Related
I have two windows forms in my application. First one is Main form and the second one is lookup form. I'm trying to open lookup form from the main form in a text box key leave event and then I'm opening the lookup form. My lookup form has a data grid view and I' loading it in the form load event of the lookup form. I'm reading my selected value on the grid view of the lookup window to an object. I want to close the lookup window as soon as I read the values of the selected row to the object and I want to pass it to the main form? How can I do that?
This is what I have done.
In the main form.
LookupModelType="";
if (e.KeyCode.Equals(Keys.F3))
{
foreach (Form frm in Application.OpenForms)
{
if (frm is FormControllers.Lookup)
{
if (frm.WindowState == FormWindowState.Minimized)
{
frm.WindowState = FormWindowState.Normal;
frm.Focus();
return;
}
}
}
LookupModelType = "Product";
FormControllers.Lookup newLookUp = new FormControllers.Lookup(LookupModelType);
newLookUp.ShowDialog(this);
}
In the lookup window
private string GridType = "";
public Lookup(String LookupModelType)
{
InitializeComponent();
this.GridType = LookupModelType;
}
private void Lookup_Load(object sender, EventArgs e)
{
if (GridType == "Product")
{
using(DataControllers.RIT_Allocation_Entities RAEntity = new DataControllers.RIT_Allocation_Entities())
{
dgvLookup.DataSource = RAEntity.TBLM_PRODUCT.ToList<DataControllers.TBLM_PRODUCT>();
}
}
dgvLookup.ReadOnly = true;
}
private void dgvLookup_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex < 0)
{
return;
}
int index = e.RowIndex;
dgvLookup.Rows[index].Selected = true;
}
you can do it like blow :
in the Main form :
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F3)
{
LookupForm look = new LookupForm();
var result = look.ShowDialog();
if(result == DialogResult.OK)
{
MessageBox.Show(look.data.ToString());
}
}
}
and in the look up form you have to declare 1 variable and fill whenever cell clicked
public partial class LookupForm : Form
{
public object data = new object();
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
data = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
this.DialogResult = DialogResult.OK;
this.Close();
}
}
of course, for better performance, you can declare the variable in specific type
To share data between Parent Child forms using events, here are the things needed:
A public custom event args class to share data.
Child form to have a event.
In your parent form whenever you create an instance of child, you
need to register eventhandlers
Please note that the code below is just a demo code and you will need to add null checks etc. to make it "robust".
Custom event args below
public class ValueSelectedEventArgs : EventArgs
{
public object Value { get; set; }
}
Your lookup form should have the following event declared:
public event EventHandler ValueSelected;
protected virtual void OnValueSelected(ValueSelectedEventArgs e)
{
EventHandler handler = ValueSelected;
if (handler != null)
{
handler(this, e);
}
// if you are using recent version of c# you can simplyfy the code to ValueSelected?.Invoke(this, e);
}
In my case I am firing the event on listbox selected index change and closing the form as well. Code for it:
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var i = this.checkedListBox1.SelectedIndex;
ValueSelectedEventArgs args = new ValueSelectedEventArgs();
args.Value = i;
OnValueSelected(args);
this.Close();
}
Finally in the parent form you have to register for the eventhandler
private void textBox1_Leave(object sender, EventArgs e)
{
lookup myLookup = new lookup();
myLookup.ValueSelected += MyLookup_ValueSelected;
myLookup.Show();
}
private void MyLookup_ValueSelected(object sender, EventArgs e)
{
textBox2.Text = (e as ValueSelectedEventArgs).Value.ToString();
}
I personal like to add dynamically the lookup window, and I do something like this:
//examble object
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
// the value which you want to get from datagridview
private Person _selectedValue;
// the datagridview datasource, which you neet to set
private IEnumerable<Person> _gridDataSource =
new List<Person>()
{
new Person {FirstName="Bob",LastName="Smith" },
new Person {FirstName="Joe",LastName="Doe"}
};
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode== Keys.F3)
{
var btnOk = new Button() { Text = "Ok", Anchor= AnchorStyles.None };
var btnCancel = new Button() { Text = "Cancel",Anchor= AnchorStyles.Right };
var dg = new DataGridView();
var bs = new BindingSource();
bs.DataSource = _gridDataSource;
dg.DataSource = bs;
dg.Dock = DockStyle.Fill;
dg.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
//setup a layout wich will nicely fit to the window
var layout = new TableLayoutPanel();
layout.Controls.Add(dg, 0, 0);
layout.SetColumnSpan(dg, 2);
layout.Controls.Add(btnCancel, 0, 1);
layout.Controls.Add(btnOk, 1, 1);
layout.RowStyles.Add(new RowStyle(SizeType.Percent));
layout.RowStyles.Add(new RowStyle(SizeType.AutoSize));
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent));
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
layout.Dock = DockStyle.Fill;
//create a new window and add the cotnrols
var window = new Form();
window.StartPosition = FormStartPosition.CenterScreen;
window.Controls.Add(layout);
// set the ok and cancel buttons of the window
window.AcceptButton = btnOk;
window.CancelButton = btnCancel;
btnOk.Click += (s, ev) => { window.DialogResult = DialogResult.OK; };
btnCancel.Click += (s, ev) => { window.DialogResult = DialogResult.Cancel; };
//here we show the window as a dialog
if (window.ShowDialog() == DialogResult.OK)
{
_selectedValue =(Person) bs.Current;
MessageBox.Show(_selectedValue.FirstName);
}
}
}
Here is my code:
public Form1()
{
InitializeComponent();
pBox1.AllowDrop = true;
}
private void pBox1_DragDrop(object sender, DragEventArgs e)
{
var bmp = (Bitmap)e.Data.GetData(DataFormats.Bitmap);
pBox1.Image = bmp;
pBox1.Size = new Size(100, 100);
}
private void pBox2_MouseDown(object sender, MouseEventArgs e)
{
if (DoDragDrop(pBox2.Image, DragDropEffects.Move) == DragDropEffects.Move)
{
pBox2.Image = null;
}
}
pBox1 is the pictureBox that I would like to drag into, and pBox2 is the pictureBox I would like to drag from. The error I get is an object reference not set to instance of object error, on the line "if(DoDragDrop...." within the MouseDown method.
If what you have listed is the entire code listing, you are never setting pBox2.Image to an Image, which would cause the exception. May want to add:
private void pBox2_MouseDown(object sender, MouseEventArgs e)
{
if(pBox2.Image != null)
{
if (DoDragDrop(pBox2.Image, DragDropEffects.Move) == DragDropEffects.Move)
{
pBox2.Image = null;
}
}
}
To initialize the pBox2 to an image of some sort...
public Form1()
{
InitializeComponent();
pBox1.AllowDrop = true;
pBox2.Image = Image.FromFile(#"YourFilePath");
}
Edit
Just a note, this gets rid of your exception, but still does not implement drag drop properly. I am playing with it and will get back with you if I find a proper solution.
Edit
Possible duplicate to the following link:
Stack Overflow Thread
I got it working using the following:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.AllowDrop = true;
pictureBox1.AllowDrop = true;
pictureBox2.AllowDrop = true;
pictureBox2.Image = Image.FromFile(#"C:\TitleBar.jpg");
}
private void pictureBox2_MouseDown(object sender, MouseEventArgs e)
{
if (pictureBox2.Image != null)
{
pictureBox2.DoDragDrop(pictureBox2.Image, DragDropEffects.Move);
pictureBox2.Image = null;
}
}
private void pictureBox1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void pictureBox1_DragDrop(object sender, DragEventArgs e)
{
pictureBox1.Image = (Image)e.Data.GetData(DataFormats.Bitmap);
}
}
In my program I need to copy a Label in Windows Forms, and I implemented it the following way:
public partial class Resizer : Form
{
public Resizer()
{
InitializeComponent();
}
private Control toChange = new Control();
private Control selected = new Control();
private bool readyToMove = false;
private Point offset;
private void pictureBox4_Click(object sender, EventArgs e)
{
selected.Location = ((Control)sender).Location;
selected.Size = ((Control)sender).Size;
}
private void backClick(object sender, EventArgs e)
{
selected = null;
}
private void Resizer_Load(object sender, EventArgs e)
{
pictureBox4.MouseDown += new MouseEventHandler(this.dynamicMouseDown);
pictureBox4.MouseMove += new MouseEventHandler(this.dynamicMouseMove);
pictureBox4.MouseUp += new MouseEventHandler(this.dynamicMouseUp);
}
private void dynamicMouseDown(object sender, MouseEventArgs e)
{
toChange = (Control)sender;
selected.Location = ((Control)sender).Location;
selected.Size = ((Control)sender).Size;
readyToMove = true;
offset = new Point(PointToClient(MousePosition).X - selected.Location.X,
PointToClient(MousePosition).Y - selected.Location.Y);
}
private void dynamicMouseMove(object sender, MouseEventArgs e)
{
if (readyToMove)
{
selected.Location = new Point(PointToClient(MousePosition).X-offset.X,
PointToClient(MousePosition).Y- offset.Y);
this.Update();
}
}
private void dynamicMouseUp(object sender, MouseEventArgs e)
{
toChange.Location = selected.Location;
readyToMove = false;
}
private void button1_Click(object sender, EventArgs e)
{
PictureBox pBox = (PictureBox)CloneObject(this.pictureBox4);
this.Controls.Add(pBox);
//pBox.MouseDown += new MouseEventHandler(this.dynamicMouseDown);
//pBox.MouseMove += new MouseEventhandler(this.dynamicMouseMove);
//pBox.MouseUp += new MouseEventHandler(this.dynamicMouseUp);
//these eventhandlers did not help...
}
private object cloneObject(object o)
{
Type t = o.GetType();
System.Reflection.PropertyInfo[] properties = t.GetProperties();
Object p = t.InvokeMember("",
System.Reflection.BindingFlags.CreateInstance,
null,
o,
null);
foreach (PropertyInfo pi in properties)
{
if (pi.CanWrite)
pi.SetValue(p, pi.GetValue(o, null), null);
}
return p;
}
}
old problem:
The problem is that as soon as I click on the labelOrigin, the Window freezes and I can't close the form anymore. Why is that and how can I fix it?
Now:
As you can see, this implements a drag&drop where by pressing a button, you can duplicate a form..
the problem is, that the new pBox is not movable and does lead to graphical errors..
this code should work on a simple form after adding a button1 and a pictureBox4
In my code of RichTextBox in my Windows Phone application I have:
var link = new Hyperlink();
if (!string.IsNullOrEmpty(linkUrl))
{
link.NavigateUri = new Uri(linkUrl);
}
link.Foreground = new SolidColorBrush(Colors.Blue);
link.TargetName = "_blank";
var linkText = new Run() { Text = linkDesc };
link.Inlines.Add(linkText);
link.Click += new RoutedEventHandler(NavidateTo);
paragraph.Inlines.Add(link);
private static void NavidateTo(object sender, RoutedEventArgs routedEventArgs)
{
if (MessageBox.Show(
Constants.BrowserNavigating,
"",
MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
{
//cancel Navigation
}
else
{
StateManager.Set("Browser", "true");
}
}
How can I cancel navigation in NavidateTo method?
Update
private static void NavidateTo(object sender, RoutedEventArgs routedEventArgs)
{
if (MessageBox.Show(
Constants.BrowserNavigating,
"",
MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
{
//cancel Navigation
var phoneApplicationFrame = Application.Current.RootVisual as PhoneApplicationFrame;
if (Application.Current.RootVisual as PhoneApplicationFrame != null)
phoneApplicationFrame.Navigating += new NavigatingCancelEventHandler(NavigationService_Navigating);
}
else
{
StateManager.Set("Browser", "true");
}
}
public static void NavigationService_Navigating(object sender, NavigatingCancelEventArgs e)
{
{
e.Cancel = true;
}
}
This doesn't help
Use this.NavigationService.StopLoading();
Also consider this method:
Subscribe to the Navigating event.
void NavigationService_Navigating(object sender, NavigatingCancelEventArgs e)
{
// Don't allow refreshing of a static page
if (DO SOME CHECKS)
{
e.Cancel = true;
}
}
And take a look at this article over at msdn.
http://msdn.microsoft.com/en-us/library/system.windows.navigation.navigationservice.navigating.aspx
I have stack of images in a grid and i want to implement a slide show for it.I am using Microsoft VS 2010 Express Edition for Windows phone for implemenitng this.Can someone help ? The code is :
using System;
using System.Collections.Generic;
using System.Windows.Threading;
namespace swipe
{
public partial class MainPage : PhoneApplicationPage
{
// private DispatcherTimer tmr = new DispatcherTimer();
private List<string> images = new List<string>();
private int imageIndex = 0;
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
// tmr.Interval = TimeSpan.FromSeconds(5);
// tmr.Tick += new EventHandler(tmr_Tick);
LoadImages();
ShowNextImage();
}
private void LoadImages()
{
images.Add("/images/Hydrangeas.jpg");
images.Add("/images/Jellyfish.jpg");
images.Add("/images/Koala.jpg");
images.Add("/images/Tulips.jpg");
}
private void ShowNextImage()
{
// String bi = new BitmapImage(new Uri(images[imageIndex], UriKind.Relative));
myImg.Source = new BitmapImage(new Uri(images[imageIndex], UriKind.Relative));
imageIndex = (imageIndex + 1) % images.Count;
}
//void tmr_Tick(object sender, EventArgs e)
//{
// ShowNextImage();
//}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
//if (!tmr.IsEnabled)
//{
// tmr.Start();
//}
base.OnNavigatedTo(e);
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
//tmr.Stop();
base.OnNavigatedFrom(e);
}
private void Play_Click(object sender, RoutedEventArgs e)
{
ShowNextImage();
}
}
}
Here's a quick example of one way of doing this. It doesn't use a grid of images but I'm sure you can adjust this as you need to.
Edit: reread the title. If you want this to advance on button click get rid of the timer and call ShowNextImage() in the click event.
The page includes the following XAML:
<Image x:Name="myImg" />
The code behind looks like:
private DispatcherTimer tmr = new DispatcherTimer();
private List<string> images = new List<string>();
private int imageIndex = 0;
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
tmr.Interval = TimeSpan.FromSeconds(5);
tmr.Tick += new EventHandler(tmr_Tick);
LoadImages();
ShowNextImage();
}
private void LoadImages()
{
// list the files (includede in the XAP file) here
images.Add("/images/filename1.jpg");
images.Add("/images/filename2.jpg");
images.Add("/images/filename3.jpg");
images.Add("/images/filename4.jpg");
}
private void ShowNextImage()
{
var bi = new BitmapImage(new Uri(images[imageIndex], UriKind.Relative));
myImg.Source = bi;
imageIndex = (imageIndex + 1) % images.Count;
}
void tmr_Tick(object sender, EventArgs e)
{
ShowNextImage();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (!tmr.IsEnabled)
{
tmr.Start();
}
base.OnNavigatedTo(e);
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
tmr.Stop();
base.OnNavigatedFrom(e);
}
Sample code which shows using a button to advance code can be downloaded from http://cid-cc22250598bf7f04.office.live.com/self.aspx/Public/SlideShowDemo.zip
The easy way is to create a collection of images, and and go to next image in the collection when you go to next page in a pivot page.
A other solution is to create a usercontrol.
Here is a guide how to do it in silverlight ( but not in WP7, but it is very similar ).