I wrote a function to dynamically add elements to the "Panel".
public int State;
public Point Point = new Point(0, 0);
public void DialogAdd(string message, string author)
{
var d = new DialogMessage();
if(State == 0)
{
d.BackColor = Color.FromArgb(255, 237, 241, 245);
State = 1;
}
else
{
State = 0;
}
d.Controls["name"].Text = author;
d.Location = new Point(0, Point.Y);
d.Controls["msg"].Text = message;
Point.Y += d.Size.Height;
Controls["panel1"].Controls.Add(d);
}
DialogMessage is UserControl, that haves property "AutoSize=true" on all components.
This panel has got the AutoScroll property, so has got scrollbars.
The problem is that the elements are added in different ways, depending on the position of the scrollbar. If the scrollbar is at the top, then all added as needed.
but if at the time of adding the scrollbar at the bottom, then add items going wrong
please tell me what I'm doing wrong and how to fix it? Thank you. sorry for bad english
When placing the controls inside the panel, you have to compensate for the scroll position:
Basically, try using this line:
d.Location = new Point(0, panel1.AutoScrollPosition.Y + Point.Y);
Related
I have a list of texts placed in WrapPanel, representing nested text blocks... The texts are clickable so I wanted to emphasize it, so when user enters mouse over them, I make them bigger (basically I'm just increasing the font by one). The problem is that this changes size of the framework element which affects layout in WrapPanel, meaning the panel can move last item into next row. Normally there is enough space, or even if not, it's not a problem when hovering over some text in the middle. But if user want's to click last element when it's near the edge of the panel, he basically can't. Because as soon as the element grows, it moves to next row and the cursor is not longer over it, so it shrinks again and panel moves it back to first row, where it is under cursor again, and so on...
Here you can see this scenario:
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
var wp = new WrapPanel() {
Background = Brushes.Blue,
Orientation = Orientation.Horizontal,
VerticalAlignment = VerticalAlignment.Top,
Children = {
createChild(),
createChild(),
createChild(),
createChild(),
}
};
Content = new Grid() {
Background = Brushes.Gray,
Children = { wp }
};
}
private UIElement createChild() {
var g = new Grid() {
Width = 100,
Height = 20,
Margin = new Thickness(5),
Background = Brushes.Red,
};
g.MouseEnter += (s, e) => { g.Width *= 2; g.Background = Brushes.White; };
g.MouseLeave += (s, e) => { g.Width *= .5; g.Background = Brushes.Red; };
return g;
}
}
How can I avoid it?
I was thinking of some "margin" property I could specify in WrapPanel so it will move the child to next row earlier when it's close to the edge whiting that margin (even if it could actually fit), but I didn't found such thing.
I want to include the colored panel below into my form:
For this I have created custom panel which will change Border color based on Radio Button selection. My panel code is
InfoPanel.cs
class InfoPanel : Panel
{
private Color colorBorder = Color.Transparent;
public InfoPanel()
: base()
{
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawRectangle(
new Pen(
new SolidBrush(colorBorder), 2),
e.ClipRectangle);
e.Graphics.DrawLine(new Pen(new SolidBrush(colorBorder), 0), 50, 0, 50, 50); //drawing a line to split the child & parent info panel
}
public Color BorderColor
{
get
{
return colorBorder;
}
set
{
colorBorder = value;
}
}
}
In my form,
1. created one parent Info Panel
2. created one child panel with Picture box
3. One label in parent info panel to show the information
Now for the parent panel I am changing the colors [back, border] & text based on user selection & for child panel I am not changing border color but updating back color based on user selection.
Below is the code for changing the panel colors, image, text update:
private void rbIPAddress_CheckedChanged(object sender, EventArgs e)
{
if (rbIPAddress.Checked)
{
ParentInfoPanel.BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFFEE");
ParentInfoPanel.BorderColor = System.Drawing.ColorTranslator.FromHtml("#DADA85");
ChildInfoPanel.BackColor = System.Drawing.ColorTranslator.FromHtml("#F6F6D8");
InfoPanelPictureBox.Image = Template.InfoPanelInfoImage;
Infolabel.Text = "IP Address is already configured. You can switch to Forward Lookup Zone by choosing other configuration. *IP Address \ncan be either LB IP Address.";
txtBoxIPAddress.Enabled = true;
textBoxPort.Enabled = true;
}
else
{
Infolabel.Text = "";
txtBoxIPAddress.Text = "";
txtBoxIPAddress.Enabled = false;
textBoxPort.Enabled = false;
}
}
private void rbForwardLookupZone_CheckedChanged(object sender, EventArgs e)
{
if (rbForwardLookupZone.Checked)
{
ParentInfoPanel.BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFFEE");
ParentInfoPanel.BorderColor = System.Drawing.ColorTranslator.FromHtml("#DADA85");
ChildInfoPanel.BackColor = System.Drawing.ColorTranslator.FromHtml("#F6F6D8");
InfoPanelPictureBox.Image = Template.InfoPanelInfoImage;
Infolabel.Text = "Forward Lookup Zone is already configured. You can switch to IP Address by choosing other configuration and \nchanging port number will affect Firewall rules.";
textBoxControlPlane.Enabled = true;
if (string.IsNullOrEmpty(textBoxControlPlane.Text))
{
textBoxControlPlane.Text = Constants.DefaultControlPlaneDomain;
}
}
else
{
Infolabel.Text = "";
textBoxControlPlane.Text = "";
textBoxControlPlane.Enabled = false;
}
}
Note: used next line character to display label text in multiple line
Output: Everything is ok but in the end of label text I am getting another rectangle box. I'm wondering why is showing like this? Am I doing wrong? Please help me on this.
The issue is that you're using e.ClipRectangle. It informs you which portion of the control needs to be redrawn. This is sometimes only a small part of the control rather than the whole thing (in your case the area of the extra rectangle). Always draw the control's full rectangle instead.
Also, you must dispose of both the Pen and SolidBrush. Failing to do so causes memory leaks. Utilize the using statement.
using(SolidBrush brush = new SolidBrush(colorBorder))
using(Pen pen = new Pen(brush, 2))
{
e.Graphics.DrawRectangle(pen, new Rectangle(0, 0, this.ClientSize.Width - 1, this.ClientSize.Height - 1));
e.Graphics.DrawLine(pen, 50, 0, 50, 50);
}
i am trying to do scroll and mousewheel, and dragging in a panel with textboxes in it. I have to let some of the textboxes with fixed position, but doing this, i have some problem with pixels, while Wheeling or dragging or scrolling. I do not know if there is some sort of way of doing this without this problem. If anyone know an answer and he/she are willing to help, please, feel free.
I will put the code i use for this:
This code is Inside a function that is called from Dynamics NAV and will create the operations:
#region PROPRIETES DU PANEL
pnOperation.Name = idOperationL.ToString();
pnOperation.BorderStyle = BorderStyle.FixedSingle;
pnOperation.BackColor = Color.LightGray;
pnOperation.Size = new Size(220, 40);
pnOperation.Top = posOperationL * 40;
pnOperation.AllowDrop = true;
if (nRolesG > 6)
{
//I fixed the operation here so they will stay at position 0
pnOperation.Top = posOperationL * 40;
pnOperation.Left = 0;
MainPanel.MouseWheel += (senderL, eL) =>
{
pnOperation.Left = 0;
pnOperation.Invalidate();
};
MainPanel.Scroll += (senderL, eL) =>
{
pnOperation.Left = 0;
pnOperation.Invalidate();
};
}
#endregion
Screenshot
Screenshot
Thanks in advance
I have a Winforms app that allows the user to drag and drop some labels around the screen.
The objective being to put the matching labels on top of each other.
I keep a reference to these labels in a list, and at the moment i'm checking to see if they're overlapping by doing the following.
foreach (List<Label> labels in LabelsList)
{
var border = labels[1].Bounds;
border.Offset(pnl_content.Location);
if (border.IntersectsWith(labels[0].Bounds))
{
labels[1].ForeColor = Color.Green;
}
else
{
labels[1].ForeColor = Color.Red;
}
}
The problem being that this is only good for Winforms (Bounds.Intersect). What can I do in WPF to achieve the same result?
If it makes a difference, i'm currently adding both labels to different <ItemsControl> in my view.
So thanks to the comments I was able to do what I needed.
The WPF code now looks like this for all those playing at home:
public void Compare()
{
foreach (List<Label> labels in LabelsList)
{
Rect position1 = new Rect();
position1.Location = labels[1].PointToScreen(new Point(0, 0));
position1.Height = labels[1].ActualHeight;
position1.Width = labels[1].ActualWidth;
Rect position2 = new Rect();
position2.Location = labels[0].PointToScreen(new Point(0, 0));
position2.Height = labels[0].ActualHeight;
position2.Width = labels[0].ActualWidth;
if (position1.IntersectsWith(position2))
{
labels[1].Foreground = new SolidColorBrush(Colors.Green);
continue;
}
labels[1].Foreground = new SolidColorBrush(Colors.Red);
}
}
Where in VS2010 can I find a horizontal separator control, as can be found in Outlook settings (screenshots below)?
https://jira.atlassian.com/secure/attachment/14933/outlook+settings.jpg
http://www.keithfimreite.com/Images/OutlookSettings3.gif
Note: VB.NET preferred, but C# answers okay.
If I'm not mistaken, that's just a Line control, but I don't think that control exists anymore. Here is a workaround.
label1.AutoSize = False
label1.Height = 2
label1.BorderStyle = BorderStyle.Fixed3D
Even though this has been answered, I found the following to be what I need based partly on smoore's answer.
Create a new control. Edit the code to be the following:
public partial class Line : Label
{
public override bool AutoSize
{
get
{
return false;
}
}
public override Size MaximumSize
{
get
{
return new Size(int.MaxValue, 2);
}
}
public override Size MinimumSize
{
get
{
return new Size(1, 2);
}
}
public override string Text
{
get
{
return "";
}
}
public Line()
{
InitializeComponent();
this.AutoSize = false;
this.Height = 2;
this.BorderStyle = BorderStyle.Fixed3D;
}
}
Replace Line with the control's class name you want. This will put a separator that will allow you to resize in the designer and disables adding text, changing the autosize forces the size's height to be 2 and width to be whatever you want, and disables adding text.
It's not actually included in the standard set of controls (pretty sure it used to be back in the day!) but you can easily create your own or cheat by using a GroupBox with no text and a height of 1px.
UserControl to provide the same thing: (Not written by me, source: http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/0d4b986e-3ed0-4933-a15d-4b42e02005a7/)
public partial class LineSeparator:UserControl
{
public LineSeparator()
{
InitializeComponent();
this.Paint += new PaintEventHandler(LineSeparator_Paint);
this.MaximumSize = new Size(2000, 2);
this.MinimumSize = new Size(0, 2);
this.Width = 350;
}
private void LineSeparator_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.DrawLine(Pens.DarkGray, new Point(0, 0), new Point(this.Width, 0));
g.DrawLine(Pens.White, new Point(0, 1), new Point(this.Width, 1));
}
}
I wrote a custom control just for this purpose. It supports both vertical and horizontal modes. Just install my [small] control suite and drag the separator control onto the form and place it anywhere you want.
Install-Package ALMSTWKND -Version 1.0.0
The controls will show up in the Toolbox pane after installation.