I have added an View List onto a Panel like this:
panelComponent.Controls.Add(viewListComponent);
Everything works just fine. Mouse events are handled, repainting works. But one problem: I can't move it around dynamically. If I change the control.Top variable, it just sits there without moving.
It's like the control is glued to the top left corner. Resizing the right and bottom properties works just fine! I did it without dynamically adding and then no problem.
What could be causing this, and how do I fix it?
Two possible explanations. First is the Dock property, docking it to the top keeps the control at the top of the container, no matter what you assign to the Top or Location properties.
The other one is value types, the Location property is Point, a struct. This code will not move the control:
var lbl = new Label();
panel1.Controls.Add(lbl);
var pos = lbl.Location;
pos.Y = 42; // No effect
Try using the Location property:
viewListComponent.Location = new Point(42, 42);
Related
I can't find tools or properties to place a label or a button exactly in the middle of the Form. For example, on the X axis. VS 2015.
Design time :
In my VisualStudio2010 I have these 2 buttons to center horizontally and vertically:
Its located in the toolbar "Layout". If it isn't, you can add them by clicking the small button to the right. It is also in the Format menu.
To keep centered at Runtime: Turn off all anchoring.
Note:This will keep the control at its relative position as long as it doesn't change it Size. If it does, like autosize Labels are prone to, you will have to code the Resize event. Examples are here
For controls that may change in size, you need to catch the Resize event.
In my case I have a Panel, representing a page, inside another Panel which is the workspace. The workspace is set to autoscroll. In this scenario, it's important that the control is only centered when smaller than the container.
Whenever the form changes size or when I change the content, I call this function:
private void resetPagePos()
{
int wWS = pnlWorkspace.Width;
int hWS = pnlWorkspace.Height;
int wPage = pnlPage.Width;
int hPage = pnlPage.Height;
pnlPage.Location = new Point(Math.Max(0, (wWS - wPage) / 2), pnlPage.Top = Math.Max(0, (hWS - hPage) / 2));
}
The use of Math.Max(0, ...) makes sure that if the item doesn't fit, and the scrollbars are activates, then our page scrolls correctly. If the Left or Top are set to a negative number, you would get unwanted side-effects.
Today I'm trying to use c# to fit a number of windows controls onto a panel sequentially.
I would like them to dock to the top so that I can then use BringToFront() to stack them up.
HOWEVER I would also like them to be centred. Currently, docking behaviour forces the controls to the left of the screen (however much I resize and change the location property)
I then tried to anchor my controls to the top of the panel instead. This enabled the controls to be centred and also let me resize them but anchoring has no stacking behaviour and each control overwrites the previous one.
I have researched this extensively for hours and have found no answers to this question. Is it possible to use either or both of these properties to stack my controls in the centre of the panel?
My code currently stands as so:
//Docking
userControl.Dock = DockStyle.Top;
userControl.Width = 633;
userControl.Left = (pnlRules.Width - userControl.Width) / 2; //doesn't work
Point location = new Point(((pnlRules.Width - userControl.Width) / 2), 0);
userControl.Location = location; //doesn't work
userControl.BringToFront();
OR
//Anchoring
userControl.Anchor = AnchorStyles.Top;
Point location = new Point(((pnlRules.Width - userControl.Width) / 2), 0);
userControl.Location = location;
userControl.BringToFront(); //doesn't work
My outputs are either stacked controls bound to the left panel edge (docking) or overlapping controls beautifully resized and centred (anchoring)
Thanks :)
Anya
Edit:
This captions my problem quite nicely:
http://www.techrepublic.com/article/manage-winform-controls-using-the-anchor-and-dock-properties/
This explains that using docking, the controls can be stacked next to each other. I would just like the docked, stacked controls to not be bound to the left edge of the panel.
There is no way to use a combination of docking and anchoring. A TableLayoutPanel may have worked here but I was tied to a simple Panel.
The fix was to use padding to force the control to centre:
userControl.Dock = DockStyle.Top;
pnlParent.Padding = new Padding((pnlParent.Width - userControl.Width) / 2, 0, 0, 0);
userControl.BringToFront();
My question is related to this one: How to get a screen capture of a .Net WinForms control programmatically?
I want to take a screenshot of a System.Windows.Forms.Control in C#. I'm using the DrawToBitmap method suggested in the question linked above and that works most of the time. However there are a few problems.
Problem 1:
I have two tabpages, let's call them A and B. The Control I want to take a screenshot of is in tabpage B. I want to take the screenshot when a button in tabpage A is pressed. This works most of the time, except when tabpage B hasn't been accessed yet: then the screenshot is just white. If I first access tabpage B, then go back to tabpage A and click the button to take the screenshot then it works fine. I'm guessing this is because of some loading or building of the control in the tab that hasn't been done yet, but I'm not sure what exactly (or it could be something else entirely). I've been trying to force that loading or building using ResumeLayout, PerformLayout, Show, Update, Invalidate but that doesn't work.
EDIT: Managed to solve this by using DrawToBitmap on the containing tabpage control instead of the Control itself and doing a Show on that tabpage.
Problem 2:
When I take a screenshot of a certain custom Control (a subclass of UserControl) there is a small rectangular white area in the screenshot (where there shouldn't be one obviously). The rectangular area isn't on one particular part of the control like a button or textbox so I'm not sure what's causing this. On other custom Controls (also subclasses of UserControl) it works fine, so that couldn't be the problem itself.
EDIT: Solved it, there was an empty control there that was being drawn on top of it. Setting Visible to false for that control solved it.
You can do with this code, the rest of the work and finding the correct coordinates is for the reader to do the homework.
int screenWidth = Screen.GetBounds(new Point(0, 0)).Width;
int screenHeight = Screen.GetBounds(new Point(0, 0)).Height;
Bitmap bmpScreenShot = new Bitmap(screenWidth, screenHeight);
Graphics gfx = Graphics.FromImage((Image)bmpScreenShot);
gfx.CopyFromScreen(0, 0, 0, 0, new Size(screenWidth, screenHeight));
bmpScreenShot.Save("test.jpg", ImageFormat.Jpeg);
For problem 1: If "If I first access tabpage B, then go back to tabpage A and click the button to take the screenshot then it works fine" then add in formloadevent imitating of that actions:
tabControl.SelectedIndex = IndexOfTabB;
tabControl.SelectedIndex = IndexOfTabA;
That is trick but it will work.
For problem 2: Can you compare sizes of your control and screenshot of It and give results to us? If Control.Width is not equal wirdth of bitmap screen then It is a real problem.
I want to move the location of label vertically or horizontally and it should appear from in the windows form and should be invisible at a location by moving. I want to make it through .net application using c# so can any one help me for this?
Buddy, you can use the property Location
MyLabel.Location.x = ??
MyLabel.Location.y = ??
Then hide it by using the propertyVisible
MyLabel.Visible = false`
It's difficult to tell exactly what you're trying to accomplish here. I'm going to assume that you want to move a label from its current position on the form to a new position while the application is running. I also assume that you want to make the label invisible while you're moving it so that you cannot see it move across the form.
You can do this easily by setting the Location property of the label you want to move to its new location. (If necessary, like if you want to move the label a relative number of pixels, you can get the label's current position from the Location property before you set it.) The label control also has a Visible property that you can set to True or False to show/hide the control, respectively:
//Hide the label first
myLabel.Visible = false;
//Move the label to a new location on the form
myLabel.Location = new Point(30, 25);
//Make the label visible again
myLabel.Visible = true;
If I guessed wrong, and you're just trying to move the label during design-time (before you start running your program), you can just drag-and-drop it to a new position on the form.
you just drag and drop
You can make a label invisible by using the Visible Property.
myHiddenLabel.Visible = false;
I'm using Silverlight 3/C#, and I'm trying to create some XAML objects programatically in response to a user clicking on a button.
However, I can't seem to position a Canvas object that I have created - when I call SetValue() on the new Canvas with the Canvas.LeftProperty value, the browser window clears to an empty screen.
I have a simple function that exhibits the problem (I started out with something more complex):
private Canvas MakeNewCanvas()
{
Canvas newCanvas = new Canvas();
newCanvas.Width = newCanvas.Height = 50;
newCanvas.SetValue(Canvas.LeftProperty, 10);
return newCanvas;
}
and a simple button click handler that calls this:
private void MyButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
myPage.Children.Add(MakeNewCanvas());
}
NB: myPage is a Canvas object defined in my app's MainPage XAML file.
I've traced this through in the VS debugger with the SL app executing in Firefox, and whenever it executes the SetValue() line, the browser goes white and starts trying to download data (according to the status bar). I tried calling SetValue() after I've put the Canvas in the XAML tree with something like:
myPage.Children.Add(newCanvas);
newCanvas.SetValue(Canvas.LeftProperty, 10);
but it makes no difference - as soon as the SetValue() call is hit, the browser goes white.
The Canvas class seems to have no direct method of setting Left/Top on itself, apart from the SetValue() function with dependency property enum values. There's also Canvas.SetLeft() and Canvas.SetTop() but I guess they're just shims onto SetValue(). Using them didn't help anyway.
If I don't call SetValue(), then my canvas appears (and child objects I've added to it) in the SL app as you might expect, in the very top left.
If I create and position a Canvas object in Expression Blend, then the XAML generated includes Canvas.Left and Canvas.Top property values on the Canvas itself, as I would expect, so it seems to me that what I'm trying in C# should work.
But I don't seem to be able to set the left/top values myself from C# without the SL in the browser going all weird.
Any ideas?
Edit: my approach is correct, but canvas coords need to be floating point, not integer - see accepted answer for details.
Trying your code, but with the debugger catching exceptions, I get:
DependencyProperty of type System.Double cannot be set on an object of type System.Int32.
which is a really stupid gotcha - SetValue only takes Object, so you're prone to a problem like this.
Try either:
newCanvas.SetValue(Canvas.LeftProperty, 10.0);
or
Canvas.SetLeft(newCanvas, 10);
and it will probably work.
The behaviour of attached properties can be a little confusing at first.
The properties Canvas.LeftProperty and Canvas.TopProperty are applied to child objects of a canvas. They are therefore only meaningful when the child object is placed on a Canvas. Its important to understand the in WPF/SL objects do not position themselves, its up to the containing panel to decide where to put them.
I suspect the myPage is not of the Canvas type, its probably a Grid, hence it would have no idea what to do with such properties even if it bothered to look for them (which it doesn't).
In order for you to specifically position you new Canvas you need to be adding it to a Canvas.