 |
|
 |
Ravi / Eddie
Your utility class take away a lot of annoying work from winform programming. I have been thinking of building one for a long time and I am glad to find it already available. No point re-inventing the wheel
Appreciate you sharing it with the community.
best regards,
Mohit
|
|
|
|
 |
|
 |
Thanks for your comment!
/ravi
|
|
|
|
 |
|
 |
Hi
I haven't looked at the code yet but for some reason if you hold down the mouse button on the resizing corner and quickly move your mouse in a circular manner to resize the form, some of the controls get screwy.
screenshot of the issue can be found at http://i45.tinypic.com/2im5kt4.jpg[^]
Wondering if anyone else is experiencing this?
|
|
|
|
 |
|
 |
Thanks for your post. I believe it's the same problem mentioned in this[^] post. I'll look into it when time permits.
Thanks again!
/ravi
|
|
|
|
 |
|
 |
Most of the .Net inbuilt windows forms layout manager or layout capabilities are limited. You would need to resort to code to do professional layout tasks. For this reason, we created a professional layout manager called SmartLayouts to ease layout management. It is easy and powerful both simultaneously. To download demo version go to
SmartLayouts Layout Manger
|
|
|
|
 |
|
 |
Nice layout manager! It would have been quite useful before .Net 2.0, but now that we have access to TableLayoutPanel, what's the use of such a component?
TableLayoutPanel is quite easy to use and handles absolute / percentage / autosize. You can add/remove columns and rows, span a control over several rows and or columns...
|
|
|
|
 |
|
 |
True!
/ravi
|
|
|
|
 |
|
 |
Hi,
Has anyone experienced and solved flicker when resizing a tab control with some pages and controls in each page?
Even with a very simple project (tab control, 2 pages, 1 textbox per page) the tab control redraw has a lot of flicker.
Thanks.
|
|
|
|
 |
|
 |
Have you tried enabling double buffering in your form?
|
|
|
|
 |
|
 |
Hi. I have tried with and without double buffer and the effect is the same. However, looking at the flicker now, I think I was probably being too critical. It is not so bad, and is probably as good as it is going to get with fully resizable and repositioned controls.
|
|
|
|
 |
|
 |
Ravi,
Is it possible that the layoutmanger can position controls with respect to another control(Sibling controls). Is there a logic which could help me in doing that.
Thanks
Vicky (())
|
|
|
|
 |
|
 |
Good job, thanks for it
but when i run your demo project; first it does not let me to make the form more smaller than the original size it has. But after a few try to resize it from the right side (the side of buttons) of the form it lets me to make the form more smaller and i lose principle author label and text box. And when i recover the form to be able to see principle author label and text box i see principle authot textbox and ISBN textbox are sticked to each other and it becomes impossible to recover it.
|
|
|
|
 |
|
 |
hnkaraca79 wrote: it does not let me to make the form more smaller than the original size it has.
That's intentional. See line 25 in LayoutManagerDemoFrm.cs: this.MinimumSize = Size; hnkaraca79 wrote: But after a few try to resize it from the right side (the side of buttons) of the form it lets me to make the form more smaller
That seems strange. I haven't been able to reproduce this behavior. Perhaps you commented out the above line in the code?
Thanks,
/ravi
|
|
|
|
 |
|
 |
Nope, i did not even see the code I just run your example.
It is not happening in the first time, i am resizing from the right side several times. At the first times it does not let me to make the form smaller than it's original size. But later it lets me to make it more smaller and after a few tries i can make it more and more smaller. This can go on until i lose all the text box that i mentioned.
I will check/debug your code later and make a more valuable comment
|
|
|
|
 |
|
 |
Interesting. I just retried using the release build, but am still unable to reproduce the problem. Also tried to make the form smaller after minimzing and maximizing the window.
Thanks,
/ravi
|
|
|
|
 |
|
 |
I need to install vs.2005 to debug it and i could not have time to look for it, but if it helps i am sending two screenshots to your email(which is stated in your signature)
|
|
|
|
 |
|
 |
Hi
Thanks for finding this issue. I can reproduce the bug by slowly (very slow) increase the size of the form and repeat it many times. And this is a math rounding problem.
The code calculates the changes in size (pxl) of the parent form and then redistributes the changes to the controls in the percentages as user specified. So the division between integers will inevitably cause small error in each adjustment due the rounding. It is possible during many resizing back and forth, the error can accumulated to distort the layout.
This is especially apparent when you slowly increase the size of the form. For example, when you increase the size by 1 pxl, then 1/3 of 1 pxl will be rounded away during calculation. Or more likely, when you increased the size by 4 pxl, the code will loss 1 pxl after the calculation for 1/3 adjustment. That is why normal resizing and maximize/minimize the screen have no apparent distortion (hence we failed to find this bug before release the code.). But slowly changing the form size will induce gradually increased distortion.
The solution for this math rounding problem is not trivial. The Layout manager has to have the knowledge of how to handle the rounding error. While the easy layout manager is good enough for normal use, this bug is a bit annoying. I will update the code once I find a simple solution (since this is an easy layout manager).
Thanks again for your feedback.
Eddie Zhou
qing zhou
|
|
|
|
 |
|
 |
As you say, the problem results from the accumulated rounding errors due to calculating the new position by applying the percentage change to the current position - each rounding error is carried forward to the next move.
The simple solution is to apply the percentage change to the initial position and to calculate the delta from the original position. This way there is only ever one rounding error applied to a control's position.
Here are the code changes that implement my solution:
LayoutManager.alignItems() - don't set m_nWidth and m_nHeight with the container's new size i.e.
public class LayoutManager
{
#region Properties
///
/// Gets the LayoutManager's collection of items.
///
public ArrayList Items
{
get { return m_items; }
}
#endregion
#region Operations
///
/// Initializes the layout manager.
///
/// Container control.
public void init(Control container)
{
// Cache the operating context and initial dimensions
m_container = container;
m_nWidth = container.Width;
m_nHeight = container.Height;
}
///
/// Aligns the items under the layout manager's control.
///
public void alignItems()
{
// Ignore action if container has been minimized
if (m_container is Form)
{
Form f = m_container as Form;
if (f.WindowState == FormWindowState.Minimized)
return;
}
// Compute change in dimensions
int nDeltaWidth = m_container.Width - m_nWidth;
int nDeltaHeight = m_container.Height - m_nHeight;
// Align controls
foreach (LayoutManagerItem lim in m_items)
{
lim.align(nDeltaWidth, nDeltaHeight);
}
}
#endregion
#region Fields
/// Layout manager items to be aligned.
ArrayList m_items = new ArrayList();
/// The container control.
Control m_container = null;
/// Container's initial client width.
int m_nWidth = 0;
/// Container's initial client height.
int m_nHeight = 0;
#endregion
}
Note - I also moved the align method to the LayoutManagerItem class as it seemed to make more sense to me to have it there.
Added 4 new fields to LayoutManagerItem to store the initial position values, set these in the constructor and use them to calculate the control's new size/position in the align() method i.e.
public class LayoutManagerItem
{
#region Constructor
///
/// Constructs a LayoutManagerItem for a control.
///
/// The control.
/// Adjust control's left edge by this %age change in container's width.
/// Adjust control's top edge by this %age change in container's height.
/// Adjust control's right edge by this %age change in container's width.
/// Adjust control's bottom edge by this %age change in container's height.
public LayoutManagerItem(Control ctrl, uint leftAdjustPct, uint topAdjustPct, uint rightAdjustPct, uint bottomAdjustPct)
{
// the control
m_ctrl = ctrl;
// Cache the control's initial coordinates
m_left = m_ctrl.Left;
m_top = m_ctrl.Top;
m_right = m_left + m_ctrl.Width;
m_bottom = m_top + m_ctrl.Height;
// Cache the control's adjustment percentages
m_leftAdjustPct = leftAdjustPct;
m_topAdjustPct = topAdjustPct;
m_rightAdjustPct = rightAdjustPct;
m_bottomAdjustPct = bottomAdjustPct;
}
#endregion
#region Operations
///
/// Repositions/resizes a LayoutManagerItem.
///
/// Change in container's initial width.
/// Change in container's initial height.
public void align(int nDeltaW, int nDeltaH)
{
// Calculate control's new coordinates using initial coordinates
int nLeft = m_left + (int)((nDeltaW * m_leftAdjustPct) / 100);
int nTop = m_top + (int)((nDeltaH * m_topAdjustPct) / 100);
int nRight = m_right + (int)((nDeltaW * m_rightAdjustPct) / 100);
int nBottom = m_bottom + (int)((nDeltaH * m_bottomAdjustPct) / 100);
// Set control's new coordinates
m_ctrl.Left = nLeft;
m_ctrl.Top = nTop;
m_ctrl.Width = nRight - nLeft;
m_ctrl.Height = nBottom - nTop;
}
#endregion
#region Fields
/// The control.
Control m_ctrl = null;
/// Percentage by which control's left edge should be adjusted.
uint m_leftAdjustPct = 0;
/// Percentage by which control's top edge should be adjusted.
uint m_rightAdjustPct = 0;
/// Percentage by which control's right edge should be adjusted.
uint m_topAdjustPct = 0;
/// Percentage by which control's bottom edge should be adjusted.
uint m_bottomAdjustPct = 0;
/// Control's initial left position
public int m_left = 0;
/// Control's initial top position
public int m_top = 0;
/// Control's initial right position
public int m_right = 0;
/// Control's initial bottom position
public int m_bottom = 0;
#endregion
}
These fixes seem to correct the size/position problem.
Gavin
|
|
|
|
 |
|
 |
Thanks muchly, Gavin! We'll update the article (and give you credit, of course).
/ravi
|
|
|
|
 |
|
 |
Your welcome, and thanks for the excellent class in the first place
Gavin
|
|
|
|
 |
|
 |
Hi Gavin
Thanks for the elegant solution. I was thinking of setting a property for size (default to 5 pxl for triggering the align event vertically or horizontally) to smooth out the error. But I don’t like this method. Yours is much better.
Eddie Zhou
Eddie Zhou
|
|
|
|
 |
|
 |
Thanks for this - very useful!
|
|
|
|
 |
|
 |
Thanks, Matt!
-- Ravi Bhavnani
-- Eddie Zhou
|
|
|
|
 |
|
 |
Excellent code - once again: Always high quality from you guys!
|
|
|
|
 |
|
 |
Gracias!
-- Ravi
-- Eddie
|
|
|
|
 |