I require to move around a button UI element during runtime via code. How can I accomplish this?
The button UI element has these following properties:
Layout
- Width
- Height
- Left
- Top
- Margin (Left, Right, Top, Bottom)
I require to change is the Layout->Left and Layout->Right during runtime.
When I googled for it, I mostly found information on altering the Margin, and not the Left and Top values. Please guide me. I expect it's a standard question, unfortunately I have been unable to find the answer to it.
Canvas.Left and Canvas.Top are attached properties, they are set in a slightly different way than ordinary properties.
The "standard" way is to use the .SetValue method:
buttonPlayTrailer.SetValue(Canvas.LeftProperty, 500);
Another way is to use the Canvas.SetLeft and Canvas.SetTop methods (it will have the exact same result, it's just more convenient):
Canvas.SetLeft(buttonPlayTrailer, 500);
private void MoveButton(int leftOffset,int topoffset)
{
Canvas.SetLeft(buttonPlayTrailer,leftOffset);
Canvas.SetTop(buttonPlayTrailer,topoffset);
}
something like that?
Related
I have read several stack overflow questions without finding a good working solution to my problem. How can I resize my controls whenever the form is resized? I would like them to get larger or smaller when the form becomes larger or smaller.
In visual basic this was quite easy to do with the form.Zoom property (which did't really require resizing controls of course, but solved what I needed). Unfortunately this is not available in C# winforms.
Here is some other things I have tried without luck:
private void formMain_Resize(object sender, EventArgs e)
{/*
double scale;
this.scaleWidth = (float)this.Width / (float)this.origWidth;
this.scaleHeight = (float)this.Height / (float)this.origHeight;
if (this.scaleHeight > this.scaleWidth)
{
scale = this.scaleHeight;
}
else
{
scale = this.scaleWidth;
}
foreach (Control control in this.Controls)
{
control.Height = (int)(control.Height * this.scaleHeight);
control.Width = (int)(control.Width * this.scaleWidth);
this.Refresh();
// control.Font = new Font("Verdana", control.Font.SizeInPoints * heightRatio * widthRatio);
}
///////This scaling didnt work for me either
//this.Scale(new SizeF(this.scaleWidth, this.scaleHeight));
//this.Refresh();
*/
}
If I overlooked an actualy working sample of code on another stack overflow question I would love to see it, but the ones I found were similar to those above which are not working.
Perhaps I was misusing it and someone could post sample code to show for those of us who keep asking this question how to go about solving the problem.
Also, I have tried using some of the anchor/docking tools thinking they would automatically allow it but it didn't.
The best option is to use a TableLayoutPanel. Put TableLayoutPanel on the form, set the Dock property to Fill, create required rows and columns and put the controls inside the cells. Of course you need to set Dock/Anchor on the controls inside the cells, so they respond to changes to the cell size. In some situations you may need to put a Panel into a cell and drop the controls inside it, because every cell can only contain a single control. You may also need to set RowSpan/ColumnSpan on the controls.
By using a TableLayoutPanel, you have complete control over how your cotrols should be arranged. You can set absolute or percentage size for rows and columns.
Use Anchor of the control. There's an option on anchoring the top, bottom, left and right. And you're good to go.
I found an alternative solution that is working well for me, appreciate any negative or positive comments on the solution.
Using several Split Containers and Split Containers inside of Split Containers in different regions I am able to section off the primary pieces of the layout, and within there utilizing Docking and Anchoring I am able to accomplish exactly what I wanted to do - it works beautifully.
I would point out I am aware that some folks online mention split containers use lots of resources.
If your controls are in a group box, be sure to set the group boxes properties to resize. Controls inside the box are controlled by the box. The box size (unless it is inside another box) is controlled by the form.
What you are trying to do in your code is to change the sizes of the controls which isn't so good approach. Generally, the size of the Buttons and TextBoxes shouldn't be changed when you re-size your form, but they often need to move (change location). Some controls do need to change size according to the re-sized form and but in most cases only one dimension. The central controls that are used for working area (if you are developing the tool for drawing for instance) should change sizes of both dimensions. All this you can accomplish by properly setting Dock and/or Anchor properties of the controls.
textBox1.Dock = DockStyle.Bottom;
textBox1.Anchor = AnchorStyles.Bottom & AnchorStyles.Left;
All these are also easily set in the Properties panel when using designer.
But if that isn't enough for you, in rare cases, you will most definitely want to only change the location of the control:
textBox1.Location = new Point(newX, newY);
I have read several stack overflow questions without finding a good working solution to my problem. How can I resize my controls whenever the form is resized? I would like them to get larger or smaller when the form becomes larger or smaller.
In visual basic this was quite easy to do with the form.Zoom property (which did't really require resizing controls of course, but solved what I needed). Unfortunately this is not available in C# winforms.
Here is some other things I have tried without luck:
private void formMain_Resize(object sender, EventArgs e)
{/*
double scale;
this.scaleWidth = (float)this.Width / (float)this.origWidth;
this.scaleHeight = (float)this.Height / (float)this.origHeight;
if (this.scaleHeight > this.scaleWidth)
{
scale = this.scaleHeight;
}
else
{
scale = this.scaleWidth;
}
foreach (Control control in this.Controls)
{
control.Height = (int)(control.Height * this.scaleHeight);
control.Width = (int)(control.Width * this.scaleWidth);
this.Refresh();
// control.Font = new Font("Verdana", control.Font.SizeInPoints * heightRatio * widthRatio);
}
///////This scaling didnt work for me either
//this.Scale(new SizeF(this.scaleWidth, this.scaleHeight));
//this.Refresh();
*/
}
If I overlooked an actualy working sample of code on another stack overflow question I would love to see it, but the ones I found were similar to those above which are not working.
Perhaps I was misusing it and someone could post sample code to show for those of us who keep asking this question how to go about solving the problem.
Also, I have tried using some of the anchor/docking tools thinking they would automatically allow it but it didn't.
The best option is to use a TableLayoutPanel. Put TableLayoutPanel on the form, set the Dock property to Fill, create required rows and columns and put the controls inside the cells. Of course you need to set Dock/Anchor on the controls inside the cells, so they respond to changes to the cell size. In some situations you may need to put a Panel into a cell and drop the controls inside it, because every cell can only contain a single control. You may also need to set RowSpan/ColumnSpan on the controls.
By using a TableLayoutPanel, you have complete control over how your cotrols should be arranged. You can set absolute or percentage size for rows and columns.
Use Anchor of the control. There's an option on anchoring the top, bottom, left and right. And you're good to go.
I found an alternative solution that is working well for me, appreciate any negative or positive comments on the solution.
Using several Split Containers and Split Containers inside of Split Containers in different regions I am able to section off the primary pieces of the layout, and within there utilizing Docking and Anchoring I am able to accomplish exactly what I wanted to do - it works beautifully.
I would point out I am aware that some folks online mention split containers use lots of resources.
If your controls are in a group box, be sure to set the group boxes properties to resize. Controls inside the box are controlled by the box. The box size (unless it is inside another box) is controlled by the form.
What you are trying to do in your code is to change the sizes of the controls which isn't so good approach. Generally, the size of the Buttons and TextBoxes shouldn't be changed when you re-size your form, but they often need to move (change location). Some controls do need to change size according to the re-sized form and but in most cases only one dimension. The central controls that are used for working area (if you are developing the tool for drawing for instance) should change sizes of both dimensions. All this you can accomplish by properly setting Dock and/or Anchor properties of the controls.
textBox1.Dock = DockStyle.Bottom;
textBox1.Anchor = AnchorStyles.Bottom & AnchorStyles.Left;
All these are also easily set in the Properties panel when using designer.
But if that isn't enough for you, in rare cases, you will most definitely want to only change the location of the control:
textBox1.Location = new Point(newX, newY);
I'm trying to implement IScrollInfo for WPFExtensions' ZoomControl in order to be able to use this control in combination with ScrollViewer. However I'm having difficulty understanding how to correctly calculate HorizontalOffset and VerticalOffset properties and where I need to update them .At first I suspected it was TranslateX and TranslateY but that only gives you the offset relative to the position of the content from the last time the Zoom property changed and not the global offset of the viewport.
This seems like a very common need for users of ZoomControl. Has this effort been done before?
WPFExtensions seems to be very poorly documented and not very
self-explanatory, is there a good source of information to better
understand how ZoomControl works?
EDIT: I've been using this control as a reference in my efforts as it implements IScrollInfo. However the 2 controls have different approaches to invalidate the view and update data so it didn't get me very far. I prefer using WPFExtension's control since it is simpler to use, has better animation and seems to be more widely accepted.
So I wanted to change my form size on a button click and also wanted it to look like a little animation so this code help me
while (desiredWidht < this.Width)
{
this.Width += 5;
Thread.Sleep(4);
}
but there is one problem. this code expands form in right direction. how can I do the same thing in left direction.. I tried expanding the form then moving it left and moving all controls to the right but the problem was that after form reached certain width controls disappeared for some reason and when the expansion method was done they appeared back again. I cannot figure out what is the problem. What is the proper way I do this.
Try -
this.Refresh();
after moving the controls.
const int MAX_STEP = 5;
while (Width < desiredWidth)
{
int step = Math.Min(MAX_STEP, desiredWidth - Width);
SetBounds(Left - step, Top, Width + step, Height);
Refresh();
Application.DoEvents();
Thread.Sleep(4);
}
Here I've done a couple of things, first was defining a maximum step and setting the step so you'll get the exact width you desire. The big change here from the over answer was the SetBounds which will set all the properties atomically, I didn't have anything else going on in my sample program so I was seeing the right side gitter back and form as I was setting the width then the left (previously when testing a solution). You probably have this in some other process so you'll need to raise the event Application.DoEvents() and like mentioned by #banana you can do a Refresh(), that should be automatically called but it shouldn't hurt calling it again.
Also, I spelled Width correctly in desiredWidth, it was driving me crazy!
The "this.Property" or "this.Method" is a redundant qualifier of "this" so I've removed it from my example.
**Note, look into ClientSize.Width as it is typically what people want, you may want to also look to SetDesktopBounds
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.