How can I write a live MetroTile custom control? - c#

Using MetroFramework 1.3.5 and .NET Transitions, in Windows Forms, I have written the code for a live MetroTile. Here is the Timer Tick method used to update the tile:
private void updateTiles_timer_Tick(object sender, EventArgs e)
{
metroPanel1.BackColor = Color.Transparent;
Bitmap bm = new Bitmap(metroPanel1.Width, metroPanel1.Height);
metroTile_startStop.DrawToBitmap(bm, new Rectangle(metroTile_startStop.Location.X, metroTile_startStop.Location.Y, metroTile_startStop.Width, metroTile_startStop.Height));
metroPanel1.BackgroundImage = bm;
if (animationFlag)
{
metroTile_startStop.Text = Properties.Resources.startStopTile_alternateText;
animationFlag = false;
}
else
{
metroTile_startStop.Text = "Start";
animationFlag = true;
}
Transition.run(metroTile_startStop, "Top", metroTile_startStop.Height - 16, 4, new TransitionType_Linear(500));
}
private void metroPanel1_Click(object sender, EventArgs e)
{
metroTile_startStop.PerformClick();
}
The tile is placed inside a MetroPanel with the Size(tile.Width + 10, tile.Height + 8). metroPanel1_Click() is necessary if, during a transition, the user clicks the background bitmap.
I don't have sufficient experience and I need help in writing a custom control so I can easily reuse it in future projects. The control should have a property which sets the timer interval and the possibility to set the tile texts. If I have a working code, then I can extend it to set the tile image, customize animations etc.
Thank you!

Related

Relocate form created inside a previous form

I have two form classes (IHM and HelpPanel). In my first loaded form (IHM) I call the function bHclass_Click to create and load a HelpPanel. The PopulatePCBclasses() function basically creates all the controls that will be displayed.
My issue is that this HelpPanel is always displayed at the exact same location no matter what value is input in it's Location property.
I tried also by setting the Top and Left attributes but result was the same.
Do I miss an instruction?
private void bHclass_Click(object sender, EventArgs e)
{
HelpPanel hp = new HelpPanel();
hp.PopulatePCBclasses();
hp.Location = new Point(10, 500);
hp.Show();
}
Try setting the start position as manual before changing the location:
private void bHclass_Click(object sender, EventArgs e)
{
HelpPanel hp = new HelpPanel();
hp.PopulatePCBclasses();
hp.StartPosition = FormStartPosition.Manual;
hp.Location = new Point(10, 500);
hp.Show();
}

Tooltip background alternation

The single tooltip which shows different messages for different controls. Now the Problem is the background image is not fit/suitable to all messages. I supposed to call the draw event of the tooltip for custom size, Font etc.,
I able to successfully call the draw and Popup event of the tooltip for particular message but setting the generalized size for different messages(e.ToolTipText) is unknown to me.
public void tooltip_Popup(object sender, PopupEventArgs e)
{
e.ToolTipSize = new Size(100, 100);
}
Kindly let me know anybody have any idea about it.
you can set the size in the Popup event, like this:
private void toolTip1_Popup(object sender, PopupEventArgs e)
{
e.ToolTipSize = new Size(200, 200);
}
result of my test is this, hope it's helpful to you.
I found the answer for my Problem. The below code of POPUP event will change the tooltipsize according to the text size.
public void toolTip_Popup(object sender, PopupEventArgs e)
{
using (Font f = new Font("Arial", 12f))
{
e.ToolTipSize = TextRenderer.MeasureText(
toolTips.GetToolTip(e.AssociatedControl), f);
}

How can i show an image while my application is loading

i have and application windows form .net and my form1 takes a lot of time to appear because in it's event form1_Load does a lot of operation.
My goal is to show an image while the operation are being done.
private void form1_Load(object sender, EventArgs e)
{
methode1();
}
While my methode1() is working, my form doesnt show, i want to show an image on the screen while my methode1() is working because while methode1() is working, there is nothing on the screen.
All the visual things in .net is done on form. You can do it by creating an small form which contains an image load it before module1() and after completing module1() close it. Just below..
private void form1_Load(object sender, EventArgs e)
{
Form f = new Form();
f.Size = new Size(400, 10);
f.FormBorderStyle = FormBorderStyle.None;
f.MinimizeBox = false;
f.MaximizeBox = false;
Image im = Image.FromFile(path);
PictureBox pb = new PictureBox();
pb.Dock = DockStyle.Fill;
pb.Image = im;
pb.Location = new Point(5, 5);
f.Controls.Add(pb);
f.Show();
methode1();
f.Close();
}
Create another form, just for loading, with a static image, and display it before your application starts to load, and destroy it afterwards. Always on top, and with no border is the usual setup for such things.
Try this code
using System.Reactive.Linq;
private void RealForm_Load(object sender, EventArgs e)
{
var g = new Splash();
// place in this delegate the call to your time consuming operation
var timeConsumingOperation = Observable.Start(() => Thread.Sleep(5000));
timeConsumingOperation.ObserveOn(this).Subscribe(x =>
{
g.Close();
this.Visible = true;
});
this.Visible = false;
g.ShowDialog();
}
This code uses Microsoft Rx to execute operations in background threads among other cool features
http://msdn.microsoft.com/en-us/data/gg577609.aspx
In order for this code to work you need to reference two nuget packages: Rx and Rx windows forms
https://nuget.org/packages/Rx-Main/1.0.11226
https://nuget.org/packages/Rx-WinForms/1.0.11226
(splash screen c# -- google it)
Here's what I just found:
http://msdn.microsoft.com/en-us/library/aa446493.aspx
How about using the built in SplashScreen class?
http://msdn.microsoft.com/en-us/library/system.windows.splashscreen.aspx

.NET C# MouseEnter listener on a Control WITH Scrollbar

As long as the mouse is over a specific control, we show some form. When the mouse leaves the control, we hide the control after a small timeout. This is standard hover behavior.
However, when a control (for example a Treeview) has a scrollbar, and the mouse is ON or OVER the scrollbar, the events don't fire ...
If we could get a reference to the scrollbar control, this would solve our problem, as we would add the same listener events to the scrollbar. However, the scrollbar isn't accessible as far as I know ...
How can we solve this problem ?
The scrollbar is in the tree view's non-client area. When the mouse moves there, it starts generating non-client messages like WM_NCMOUSEMOVE and WM_NCMOUSELEAVE. You would have to sub-class the TreeView and override WndProc() to detect these message.
This doesn't really solve your problem though, you'll still have a hard time with edge cases. A low-tech approach with a Timer always works:
private Form frmPopup;
private void treeView1_MouseEnter(object sender, EventArgs e) {
timer1.Enabled = true;
if (frmPopup == null) {
frmPopup = new Form2();
frmPopup.StartPosition = FormStartPosition.Manual;
frmPopup.Location = PointToScreen(new Point(treeView1.Right + 20, treeView1.Top));
frmPopup.FormClosed += (o, ea) => frmPopup = null;
frmPopup.Show();
}
}
private void timer1_Tick(object sender, EventArgs e) {
Rectangle rc = treeView1.RectangleToScreen(new Rectangle(0, 0, treeView1.Width, treeView1.Height));
if (!rc.Contains(Control.MousePosition)) {
timer1.Enabled = false;
if (frmPopup != null) frmPopup.Close();
}
}
I think there are several different ways to do this, but the key is your desire to have a timeout on the action. I think a combination of two techniques might work:
Put the control on a panel, docked to fill, and use the MouseEnter of the panel to turn on your behavior -- this will include the control's scrollbar. You can use the MouseLeave event of the panel as well, but you'll have to check the cursor's position to ensure it hasn't moved into the contained control. This method is mostly reliable, but moving the mouse quickly can confuse it.
If you combine this with a timer that starts when your shown/hidden control is shown and check the cursor position periodically. This will work, but your timeout before hiding the control won't necessarily be consistent (because the timer starts when they enter the control). You could stop/start the timer on mousemoves in the control to alleviate this somewhat.
I put together a project of the different methods I tried here: http://lovethedot.s3.amazonaws.com/100609StackoverflowScrollbarQuestion.zip
By docking the control you want to track in the panel, it essentially wraps it and you'll get MouseEnter at the very edge of the tracked control:
private void panel1_MouseEnter(object sender, EventArgs e)
{
this.Text = "in";
}
private void panel1_MouseLeave(object sender, EventArgs e)
{
if (!new Rectangle(new Point(0, 0), panel1.Size).Contains(panel1.PointToClient(Control.MousePosition)))
this.Text = "out";
}
You're tracking entry into the panel surrounding the control, and exit from that panel provided the cursor isn't inside the tracked control.
To get a better "leave" experience, it's combined with a Timer that checks to see where the cursor is as well:
private void listBox3_MouseEnter(object sender, EventArgs e)
{
button1.Visible = true;
visibleTimer.Stop();
visibleTimer.Start();
}
void visibleTimer_Tick(object sender, EventArgs e)
{
if (!new Rectangle(new Point(0, 0), listBox3.Size).Contains(listBox3.PointToClient(Control.MousePosition)))
{
visibleTimer.Stop();
button1.Visible = false;
}
}

ToggleButton in C# WinForms

Is it possible to create a toggle button in C# WinForms? I know that you can use a CheckBox control and set it's Appearance property to "Button", but it doesn't look right. I want it to appear sunken, not flat, when pressed. Any thoughts?
You can just use a CheckBox and set its appearance to Button:
CheckBox checkBox = new System.Windows.Forms.CheckBox();
checkBox.Appearance = System.Windows.Forms.Appearance.Button;
Check FlatStyle property. Setting it to "System" makes the checkbox sunken in my environment.
You may also consider the ToolStripButton control if you don't mind hosting it in a ToolStripContainer. I think it can natively support pressed and unpressed states.
thers is a simple way to create toggle button. I test it in vs2010. It's perfect.
ToolStripButton has a "Checked" property and a "CheckOnClik" property. You can use it to act as a toggle button
tbtnCross.CheckOnClick = true;
OR
tbtnCross.CheckOnClick = false;
tbtnCross.Click += new EventHandler(tbtnCross_Click);
.....
void tbtnCross_Click(object sender, EventArgs e)
{
ToolStripButton target = sender as ToolStripButton;
target.Checked = !target.Checked;
}
also, You can create toggle button list like this:
private void Form1_Load(object sender, EventArgs e)
{
arrToolView[0] = tbtnCross;
arrToolView[1] = tbtnLongtitude;
arrToolView[2] = tbtnTerrain;
arrToolView[3] = tbtnResult;
for (int i = 0; i<arrToolView.Length; i++)
{
arrToolView[i].CheckOnClick = false;
arrToolView[i].Click += new EventHandler(tbtnView_Click);
}
InitTree();
}
void tbtnView_Click(object sender, EventArgs e)
{
ToolStripButton target = sender as ToolStripButton;
if (target.Checked) return;
foreach (ToolStripButton btn in arrToolView)
{
btn.Checked = false;
//btn.CheckState = CheckState.Unchecked;
}
target.Checked = true;
target.CheckState = CheckState.Checked;
}
How about this?
Assuming you have System.Windows.Forms referenced.
var cbtnToggler = new CheckBox();
cbtnToggler.Appearance = Appearance.Button;
cbtnToggler.TextAlign = ContentAlignment.MiddleCenter;
cbtnToggler.MinimumSize = new Size(75, 25); //To prevent shrinkage!
Hope this helps ;)
This is my simple codes I hope it can help you
private void button2_Click(object sender, EventArgs e)
{
if (button2.Text == "ON")
{
panel_light.BackColor = Color.Yellow; //symbolizes light turned on
button2.Text = "OFF";
}
else if (button2.Text == "OFF")
{
panel_light.BackColor = Color.Black; //symbolizes light turned off
button2.Text = "ON";
}
}
When my button's FlatStyle is set to system, it looks flat. And when it's set to popup, it only pops up when mouses over. Either is what I want. I want it to look sunken when checked and raised when unchecked and no change while mousing over (the button is really a checkbox but the checkbox's appearance property is set to button).
I end up setting the FlatStyle to flat and wrote a new Paint event handler.
private void checkbox_paint(object sender, PaintEventArgs e)
{
CheckBox myCheckbox = (CheckBox)sender;
Rectangle borderRectangle = myCheckbox.ClientRectangle;
if (myCheckbox.Checked)
{
ControlPaint.DrawBorder3D(e.Graphics, borderRectangle,
Border3DStyle.Sunken);
}
else
{
ControlPaint.DrawBorder3D(e.Graphics, borderRectangle,
Border3DStyle.Raised);
}
}
I give a similar answer to this question:
C# winforms button with solid border, like 3d
Sorry for double posting.
You can always code your own button with custom graphics and a PictureBox, though it won't necessarily match the Windows theme of your users.
I ended up overriding the OnPaint and OnBackgroundPaint events and manually drawing the button exactly like I need it. It worked pretty well.
use if command to check status and let operate as a toggle button
private void Protection_ON_OFF_Button_Click(object sender, EventArgs e)
{
if (FolderAddButton.Enabled == true)
{
FolderAddButton.Enabled = false;
}
else
{
FolderAddButton.Enabled = true;
}
}
You should look into Siticone I use it and I love it. It works exactly like a checkbox but is a toggle button. Its downside is a message box will come up every time you open Visual Studios so I just installed a tool that disables it. You can also look into Guana but I found that to have a few bugs :)
Changing a CheckBox appearance to Button will give you difficulty in adjustments. You cannot change its dimensions because its size depends on the size of your text or image.
You can try this: (initialize the count variable first to 1 | int count = 1)
private void settingsBtn_Click(object sender, EventArgs e)
{
count++;
if (count % 2 == 0)
{
settingsPanel.Show();
}
else
{
settingsPanel.Hide();
}
}
It's very simple but it works.
Warning: This will work well with buttons that are occasionally used (i.e. settings), the value of count in int/long may be overloaded when used more than it's capacity without closing the app's process. (Check data type ranges: http://msdn.microsoft.com/en-us/library/s3f49ktz.aspx)
The Good News: If you're running an app that is not intended for use 24/7 all-year round, I think this is helpful. Important thing is that when the app's process ended and you run it again, the count will reset to 1.

Categories