Ehm, umm, this means some lines should be two-lined in size. My boss think this is more simple solution, than limit displayed text to fit width and don't like horizontal scroll bar >_<
lst.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
lst.MeasureItem += lst_MeasureItem;
lst.DrawItem += lst_DrawItem;
private void lst_MeasureItem(object sender, MeasureItemEventArgs e)
{
e.ItemHeight = (int)e.Graphics.MeasureString(lst.Items[e.Index].ToString(), lst.Font, lst.Width).Height;
}
private void lst_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
e.DrawFocusRectangle();
e.Graphics.DrawString(lst.Items[e.Index].ToString(), e.Font, new SolidBrush(e.ForeColor), e.Bounds);
}
private void lst_MeasureItem(object sender, MeasureItemEventArgs e)
{
e.ItemHeight = (int)e.Graphics.MeasureString(lst.Items[e.Index].ToString(), lst.Font, lst.Width).Height;
}
private void lst_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
e.DrawFocusRectangle();
e.Graphics.DrawString(lst.Items[e.Index].ToString(), e.Font, new SolidBrush(e.ForeColor), e.Bounds);
}
To get the right display member to show up when data binding, replace
lst.Items[e.Index].ToString()
with a casted version of the property. So if your binding source is class object Car it would look like
((Car)lst.Items[e.Index]).YourDisplayProperty
Then the above functions can appropriately measure the string and draw it. :)
Helpful link
Check out this answer. It overrides the template of the listbox with a textblock which wraps the text. Hope it's useful. To solve your problem I think you shold add : ScrollViewer.HorizontalScrollBarVisibility="Disabled" . Found it here
To make binding correct, be sure to add check "lst.Items.Count > 0" to lst_MeasureItem function. Here is my example:
if (lst.Items.Count > 0)
{
e.ItemHeight = (int)e.Graphics.MeasureString(lst.Items[e.Index].ToString(), lst.Font, lst.Width).Height;
}
Everything else seems to work nicely after that.
Related
I have this C# winform with tabs on toolstrip. I need to place that plus button on extreme right "+" besides the latest tab on toolstrip. I have tried for location, but couldn't get it. Is there any other way to do this. The button should shift its position based on the new tab added or deleted
Here is a solution that uses a workaround: It owner-draws the Tab control in order to get the Bounds of each Tab..:
private void tabControl_DrawItem(object sender, DrawItemEventArgs e)
{
var page = tabControl.TabPages[e.Index];
e.DrawBackground();
e.DrawFocusRectangle();
TextRenderer.DrawText(e.Graphics, page.Text, page.Font, e.Bounds, e.ForeColor);
if (e.Index == tabControl.TabCount - 1)
button6.Left = tabControl.Left + e.Bounds.Right + 3;
}
private void buttonAdd_Click(object sender, EventArgs e)
{
tabControl.TabPages.Add("new page " + tabControl.TabCount);
}
private void buttonRemoveLast_Click(object sender, EventArgs e)
{
tabControl.TabPages.RemoveAt(tabControl.TabCount - 1);
}
You may want to change the owner-drawing to suit your application.. There a are quite a few examples around.
I have listview and it doesn't support image in second column. I try create ovalshape, but it olways is on the background of listview. So nobody can see it. I try ovalShape1.BringToFront();, but it doesn't work. Anybody can help me?
Here is a simple example with an external variable.
I assume you have added your images to an ImageList imageList1.
int imgIndex = 0;
private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
if (e.ColumnIndex == 1)
e.Graphics.DrawImage(imageList1.Images[imgIndex], e.Bounds);
else e.DrawDefault = true;
}
private void button1_Click(object sender, EventArgs e)
{
imgIndex++;
listView1.Invalidate();
}
You would more likely want to get the imageindex from data in the ListViewItem separately for each Row, maybe like this:
//..
e.Graphics.DrawImage(imageList1.Images[Convert.ToInt16( e.SubItem.Text) ], e.Bounds);
//..
As usual error checking is up to you.
Also note the Invalidate, which triggers the Paint and the subsequent DrawSubItem event, necessary after you have changed the imageindex. When the underlying values change, the system will take care of that.
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);
}
I have PictureBox in my Windows Form.When I click in some part of the picture, some label text needs to be changed.
Is there any way to know is it clicked in some part of the image?
I didn't gave any code because i think you can understand my problem whitout it.
I suppose you have rect as your Rectangle with some initialization, its coordinates are relative to your PictureBox:
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
if(rect.Contains(e.Location)){
//your code here
}
}
You should create mapping for your image, something like this:
Rectangle rect1 = new Rectangle(/*coordinates of part of image*/);
OnClick(object sender, MouseEventArgs e)
{
if (rect1.Contains(e.Location))
{
//handler for this part
}
}
Create List of Rectangle containing areas you want to be interactive.
let say:
private static List<Rectangle> rects;
populate it with desired coordinates in some order.
then in OnClick event
OnClick(object sender, MouseEventArgs e)
{
for(int i=0; i<rects.Count; i++)
if (r.Contains(e.Location))
ActionForArea(i);
}
also
private static void ActionForArea(int number)
{
//do sth
}
I'm in the stages of making a program which will require a tabpage to flash when an event happens
I've googled around, and i came across this: Blink tab header on receiving event. This is similar, but uses WPF, and i'm using WinForms, and i'm not even sure that does what i want :L
I've also found this: C#: Flash Window in Taskbar via Win32 FlashWindowEx. This is what i want, but obvious for the whole form, and in the taskbar, not 'in form'
Anyone got any ideas?
I'm not saying this is the best way or even a great way to accomplish this, but it does work. I've used code similar to this when I needed to something similar.
The tabControl1 has two tabs and I blink tab 1 (the second tab).
For my example that I threw together, I set tabControl1's DrawMode property to "OwnerDrawFixed" and then a couple of buttons which start/stop the timer. The interval was something like 750ms but you could choose whatever, of course. On a timer1_Tick event, I swap out the current color and tell the tabControl1 to refresh itself. That'll make the DrawItem event get raised and then I either draw the rectangle the current color if it is tab page 1 or the backcolor if not. Then I draw the tabpage's text.
It works. Could use some tweaking for sure. Give it a whirl!
public partial class Form1 : Form
{
Color currentColor = Color.Green;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (currentColor == Color.Yellow)
currentColor = Color.Green;
else
currentColor = Color.Yellow;
tabControl1.Refresh();
}
private void button2_Click(object sender, EventArgs e)
{
timer1.Stop();
}
private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
if (timer1.Enabled && e.Index == 1)
{
e.Graphics.FillRectangle(new SolidBrush(currentColor), e.Bounds);
}
else
{
e.Graphics.FillRectangle(new SolidBrush(this.BackColor), e.Bounds);
}
Rectangle paddedBounds = e.Bounds;
paddedBounds.Inflate(-2, -2);
e.Graphics.DrawString(tabControl1.TabPages[e.Index].Text, this.Font, SystemBrushes.HighlightText, paddedBounds);
}
}