Hide image when click outside of image in wpf - c#

When my WPF application loads, an image is shown in center.
how can i handle mouse click outside of image. when user clicks outside of image it hide.
My code is in c#.

You can simply add a handler to the top level control, eg. Grid, Window, etc. In that handler, you can check whether the control that was clicked on was the Image and if it wasn't, then you could hide it:
The XAML:
<Grid PreviewMouseLeftButtonDown="Grid_PreviewMouseLeftButtonDown">
...
<Image Name="TheImage" Source="/WpfApplication2;component/Images/Add_16.png" />
...
</Grid>
The code behind:
private void Grid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.OriginalSource != TheImage)
{
TheImage.Visibility = Visibility.Hidden;
}
}
While this fulfils your requirements, it should be noted that once hidden, the Image will no longer be 'clickable'.

just put the code MyImage.Visibility = System.Windows.Visibility.Hidden; in whichever event you want to capture.
for eg:
private void MyButton_Click_1(object sender, RoutedEventArgs e)
{
MyImage.Visibility = System.Windows.Visibility.Hidden;
}
private void MyTextbox_PreviewMouseDown_1(object sender, MouseButtonEventArgs e)
{
MyImage.Visibility = System.Windows.Visibility.Hidden;
}
private void MyWindow_MouseDown(object sender, MouseButtonEventArgs e)
{
MyImage.Visibility = System.Windows.Visibility.Hidden;
}
where MyImage is the name of image, MyTextbox is the name of textbox, MyButton is the name of Button and MyWindow is the name of Main Window

you can simply write
YourImageName.Visibility = Visibility.Hidden;
Write this code to any of the control i.e. TextBox or Button.

first click on the form to select it. then go to the event's section (near property section) and double-click the click event to make a function call when a form is clicked. in the code compare the sender object with the IsEqual(obj) method and see the sender is same image or it's not. if not hide it. :)

You can handle the click event of Application current window , and inside that event you can check if the mouse position is within that image or outside of that image , on basis of this you can set your image visibility condition you prefer .
Code sample example :
//registering event
Application.Curent.mainWindow.MouseRightButtonDown += MainWindow_MouseRightButtonDown;
//event implementation
void MouseRightButtonDown(object sender , MouseButtonEventArgs e)
{
//here you can check the ui element for image control using sender
//below will let you know the position of Click
e.GetPosition(// pass the ui element here)
}
Note : The above code shown is at app level click handling . If you
dont want at app level you can take the parent xaml within which the
image is present and do the same

Related

Event that would listen to any label click in form

Well, I'm making a chess game that's based on labels. I need to listen for label click, so when user clicks on an label, I get the name of label he clicked. I know I can do it for each label, but is there an universal event that would help me do the same thing for all of them in one event / loop?
Suppose you have taken 64 labels.
In windows form, on click event of Label1 you will write following code:
private void Label1_Click(object sender, EventArgs e)
{
var label = sender as Label;
MessageBox.Show(label.Name);
}
For remaining 63 Lables, In Design view, select all 63 lables by using Ctrl key --> Go to Property window --> Under Event option select Click option --> From dropdownlist select 'Label1_Click' option.
Just finish & run the application.
You can use a Panel
structure to group your labels and then call the desired event on that Panel, so it will trigger whenever you click one of it's elements.
Another solution would be to identify your label with the coordinates of the mouse click (the amount of code that requires depends how you placed them of course).
Like mentioned in the comments you can assign one event to all...
List<Label> lbls = this.Controls.OfType<Label>().ToList();
foreach (var lbl in lbls)
{
lbl.Click += lbl_Click;
}
void lbl_Click(object sender, EventArgs e)
{
Label lbl = sender as Label;
MessageBox.Show(lbl.Name);
}
You can assign these methods to every label you need to manage in the VS form designer (you go to events of controls, at the click line and select the method in the list instead of double click on it):
private void Label_Click(object sender, EventArgs e)
{
var nameLabel = ( sender as Label )?.Name ?? "Error";
// ...
}
private void Label_Enter(object sender, EventArgs e)
{
( sender as Label ).Cursor = Cursors.Hand;
}
private void Label_Leave(object sender, EventArgs e)
{
( sender as Label ).Cursor = Cursors.Default;
}
Cursor change added for convenience if you want.
If you want to dynamically assign events, you can use the #caner answer, and you can group all in a panel to parse Panel.Controls and assign event.
You can create a custom label class that inherits from Label. You can then subscribe to the Click event of the base class and do your thing.
public class MyLabel : Label
{
public MyLabel()
: base()
{
Click += ProcessClickEvent;
}
private void ProcessClickEvent(object sender, System.EventArgs e)
{
// Do what you want to do
}
}

Chaning the image according to what button is clicked

I have this interface and I want the middle image to change according to which button is clicked. What would I need in order to do this?
http://i62.tinypic.com/kbx9z.png
I assume that you have a list of images. Then you can assign a button's Tag property to index of an image. Then assign each button's click event to a sinle event such as
private void buttonClicked(object sender, EventArgs e)
{
this.pictureBox1.Image = this.imageList[(int)((Button)sender).Tag];
}

How to write a common Event Handler for a UIElement of same type?

In a WPF application, suppose there are 'n'-number of pictures of type image and if on clicking any picture (i.e. of type image), its visibility should collapse. Now a normal way to do this would be to to write the code to collapse for every 'Click' event for every picture.
Is there an alternative way so that the application can understand that whenever any UIelement(picture) of type image is clicked then that particular element(picture) should collapse?
I want to reduce the code, how can I achieve this?
You can take advantage of the fact that these are Routed Events, and set a single handler on a parent element.
This allows a single event handler to handle all events of the child controls. The OriginalSource property of the event args will provide the UIElement that was clicked, if, for example, you subscribed to UIElement.MouseLeftButtonDown or a similar "shared" event.
You would do this by adding, in your XAML, to your container:
<Grid UIElement.MouseLeftButtonDown="CommonClickHandler">
<!-- Your elements here -->
Then, in your code behind:
private void CommonClickHandler(object sender, MouseButtonEventArgs e)
{
Image picture = e.OriginalSource as Image; //OriginalSource is the original element
if (picture != null)
picture.Visibility = Visibility.Collapsed;
}
You can add global handler using EventManager.RegisterClassHandler like this -
public MainWindow()
{
InitializeComponent();
EventManager.RegisterClassHandler(typeof(Image), Image.MouseDownEvent,
new RoutedEventHandler(OnMouseDown));
}
private void OnMouseDown(object sender, RoutedEventArgs e)
{
(sender as Image).Visibility = System.Windows.Visibility.Collapsed;
}
You can register the method you are using on multiple event handlers and get access to the particular control by using Object sender parameter and casting it to the type of control you are using.
myControl.Click += new EventHandler(myGenericClickMethod);
public void myGenericClickMethod(Object sender, EventArgs e)
{
Image myImage = (Image) sender;
myImage..Visibility = System.Windows.Visibility.Collapsed;
}

Auto expand the window by pressing a button

I am using “Microsoft Visual Studio 2010” and C# language. My user interface look like this(before user click the Advance button):
If user click Advance button, I want it to show the rest of the window as shown in the picture bellow:
Can you please tell me how can have all these information hidden till the user click the Advance button? How can I have a smaller window first, as shown in the first figure. And when the user press the advance button, it will expand and show the rest.
If you can show me with details, I would really appreciate it
All WinForms controls, including the Form itself, have an AutoSize property. When set to true, it causes the control to automatically resize itself to fit its contents.
Therefore, you should place your "advanced" controls into a UserControl and add that UserControl to your form (or you can use a Panel if you're lazy). Then, when the "Advanced" button is clicked, toggle the visibility of your UserControl. The form should automatically adjust its size accordingly.
Alternatively, you could add SplitContainer to your form, which has the ability to collapse one of its two panels. The "Advanced" button would then toggle the state of the Panel2Collapsed property to expand/collapse the bottom panel.
Note: Grammatically, the caption of that button should be "Advanced", not "Advance". For an improved user experience, I recommend adding some kind of indicator that the button expands the available information on the window, rather than submitting it or opening a second window. Most "expander" buttons accomplish this using a downward-facing arrow, e.g.
You could use an image for this, or a Unicode glyph. For example, ▼, the black down-pointing triangle. Change it to an upward-pointing triangle when the panel is expanded.
1.Add a panel to bottom of your form and add all the controls that you need to display in the advanced button click.
2.change the following properties of both the panel and your form,
> AutoSize >> true
> AutoSizeMode >> GrowAndShrink
3.then in form load event you can use like following
private void Form1_Load(object sender, EventArgs e)
{
panel1.Visible = false;
}
4. then in advanced button click event
private void button1_Click_1(object sender, EventArgs e)
{
//panel1.Visible = true;
string value1 = button1.Text;
switch(value1)
{
case "Expand":
panel1.Visible = true;
break;
case "Reduce":
panel1.Visible = false;
break;
}
button1.Text = "Reduce";
if(panel1.Visible==true)
{
button1.Text = "Reduce";
}
else if(panel1.Visible==false)
{
button1.Text = "Expand";
}
}
At first set the following properties visible false
like all lebels and text boxs. then in the click event of the advanced button set all properties visible true.
OnLoad event of your first form set every control or groupbox (whichever you are using) visibility as false.
And on advance buttonclick event make its visibility true.
Code as follows:
private void FirstForm_Load(object sender, EventArgs e)
{
controlName.Visible=false;
}
private void btnAdvance_Click(object sender, EventArgs e)
{
controlName.Visible=true;
}
MSDN For Visibility Property:
http://msdn.microsoft.com/en-IN/library/system.windows.uielement.visibility.aspx
Hope its helpful.
you can simply do it like this,
1.Add a panel to bottom of your form and add all the controls that
you need to display in the advanced button click.
2.change the following properties of both the panel and your form,
> AutoSize >> true
> AutoSizeMode >> GrowAndShrink
3.then in form load event you can use like following
private void Form1_Load(object sender, EventArgs e)
{
panel1.Visible = false;
}
4. then in advanced button click event
private void button1_Click_1(object sender, EventArgs e)
{
panel1.Visible = true;
}
Hope this will help you and any other need this in future...!

Share an event handler across multiple controls

In my Windows forms application written in C# I have a bunch of buttons. When the user's mouse hovers over a button, I want the button's border to change.
Currently I have multiple instances of the following (a copy for each button):
private void btnStopServer_MouseEnter(object sender, EventArgs e)
{
oldColor = btnStopServer.FlatAppearance.BorderColor;
btnStopServer.FlatAppearance.BorderColor = mouseOverColor;
}
private void btnStopServer_MouseLeave(object sender, EventArgs e)
{
btnStopServer.FlatAppearance.BorderColor = oldColor;
}
Since I have a lot of buttons, the code to change the color of the button's border takes up a lot of space.
Is there any simpler way that I could do this?
You should wire-up a single MouseEnter and MouseLeave to each control that needs this functionality (rather than writing a new version of each method for each control). Assuming you're using Visual Studio, this can be done by changing the target method name for the event, in each Button's property pane. If you write the following code first, then this method will appear in the property's MouseEnter and MouseLeave events' drop-down lists.
The code would then need to check which button from which the event was fired, as follows:
private void btnWithHoverBorder_MouseEnter(object sender, EventArgs e)
{
Button eventButton = (Button) sender;
oldColor = eventButton.FlatAppearance.BorderColor;
eventButton.FlatAppearance.BorderColor = mouseOverColor;
}
private void btnWithHoverBorder_MouseLeave(object sender, EventArgs e)
{
Button eventButton = (Button) sender;
eventButton.FlatAppearance.BorderColor = oldColor;
}
I presume oldColor is a global? This might get out of sync if something "odd" happens where your MouseEnter event is fired for another button, before the corresponding MouseLeave is caught. To make this more robust, I'd consider storing the old color on the Button's .tag property, so that it's self-contained.
Eg:
private void btnWithHoverBorder_MouseEnter(object sender, EventArgs e)
{
Button eventButton = (Button) sender;
eventButton.tag = eventButton.FlatAppearance.BorderColor;
eventButton.FlatAppearance.BorderColor = mouseOverColor;
}
private void btnWithHoverBorder_MouseLeave(object sender, EventArgs e)
{
Button eventButton = (Button) sender;
eventButton.FlatAppearance.BorderColor = (Color)eventButton.tag;
}
(The tag is basically a hook on which to tag "anything" relevant to a specific instance of a control, that there is not already a property for. It's of type Object which means you can tag anything there, but when you read from it, you need to cast it back to whatever type you put there in the first place. But because it's an Object you can put anything there, including eg a custom class that contains multiple properties, or an array, etc if you need to tag a control with more than one thing).

Categories

Resources