سؤال

On the main form of a Windows Forms application I'm currently writing, I have a SplitContainer with a left and right panel. Controls in the right panel that have their anchor set to right (or right and left) don't stay where I put them in the designer. Periodically, the controls will shift a pixel to the left (in the designer, not during runtime). For controls anchored both left and right, the control will shrink, but for controls just anchored right, the entire control moves left while staying the same size. Does anyone know why this happens or how to avoid it? Right now, the only thing I can do is periodically move them back.

Note: My Windows Forms designer is currently set up with LayoutMode = SnapToGrid, Snap to Grid = true, and a grid size of 5 x 5.

Edit: I've managed to find a way to reproduce this issue in Visual Studio 2012, finally. Create a new Windows Forms project, with the same designer settings that I'm using, and add a SplitContainer to the form. Leave it docked to fill (or use anchors to all sides). Now, set the SplitterDistance to 100 and the SplitterWidth to 5. Add a button to the right SplitPanel and set it's anchor to Bottom and Right. Move the button so that its right edge is flush against the side of the SplitPanel, then close and open the form. Magically, the button has shifted one pixel to the left.

Here is what it looks like before you close it (in this case the button's location is 105, 175): The form set up correctly

Here is what it looks like after you close and reopen it (now the button's location is 104, 175): The form after being closed and reopened

I hope that this example will help anyone reproduce the issue.

هل كانت مفيدة؟

المحلول

Add a button to the right SplitPanel and set it's anchor to Bottom and Left.

No, that should be Bottom and Right to get a repro for this. It is caused by the SplitterWidth assignment. Set it to 6 for example to get the button to move by 2 pixels.

This is caused by an inevitable flaw in the automatic layout calculation, the order matters a great deal and it poorly interacts with the ISupportInitialize interface, as implemented by SplitContainer. The panel's layout is calculated first but it still has a size that was based on the default SplitterWidth. The SplitContainer is next, now it notices that the panel is too wide and shrinks it. Which, because the button was already anchored to the right, causes the button to move by the same amount that the panel was too wide.

Such layout calculation order dependencies are common and inherent in the way it was designed. Particularly problematic with inherited form classes where the derived form has a different size from the base form class. Controls whose position depend on that size (anchored to the bottom or right) will end up in the wrong position.

Many possible workarounds for this, including not anchoring to the right, not changing the default splitter width and calculating the button position yourself.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top