I want to know how to let a user resize a textbox themselves at runtime. Preferably the little tabs on the borders of the textbox would popup and they can drag to resize as per most apps.
Is it possible to do this natively using winforms? if not is there a library to help do it?
I would rather use native components if possible. All my google searches turn up false positives.
The simpliest solution by using the native components would be implementing you own custom-control using the textbox and adding MouseEvents. Here is a sample that lets you drag the TextBox's bottom area, in vertical direction. Of course you should implement something more like changing the cursor's handle and repainting some areas if you would like to make a pop-up.
Here is a working concept:
bool isDrag = false;
int lastY = 0;
private void textBox1_MouseEnter(object sender, EventArgs e)
{
//Change cursor to dragging handle or implement a pop-up
}
private void textBox1_MouseDown(object sender, MouseEventArgs e)
{
//Just add 5px padding
if (e.Y >= (textBox1.ClientRectangle.Bottom - 5) &&
e.Y <= (textBox1.ClientRectangle.Bottom + 5))
{
isDrag = true;
lastY = e.Y;
}
}
private void textBox1_MouseMove(object sender, MouseEventArgs e)
{
if( isDrag)
{
textBox1.Height += (e.Y - lastY);
lastY = e.Y;
}
}
private void textBox1_MouseUp(object sender, MouseEventArgs e)
{
if (isDrag)
{
isDrag = false;
}
}
To try the code, on a new form, create a TextBox named textBox1 and wire all the MouseEvents. Try to bring your mouse on the bottom of the TextBox and drag either going top or bottom.
And do not forget to set TextBox.Multiline to true.
Better approach is to use the Anchor and Dock properties to scale controls based on their parent controls. Have a read Manage WinForm controls using the Anchor and Dock properties
Other options are TableLayoutPanel and FlowLayoutPanel base on your requirement.
TableLayoutPanel
The TableLayoutPanel control arranges its contents in a grid. Because
the layout is performed both at design time and run time, it can
change dynamically as the application environment changes. This gives
the controls in the panel the ability to proportionally resize, so it
can respond to changes such as the parent control resizing or text
length changing due to localization.
Any Windows Forms control can be a child of the TableLayoutPanel
control, including other instances of TableLayoutPanel. This allows
you to construct sophisticated layouts that adapt to changes at
runtime.
FlowLayoutPanel
The FlowLayoutPanel control arranges its contents in a horizontal or
vertical flow direction. Its contents can be wrapped from one row to
the next, or from one column to the next. Alternatively, its contents
can be clipped instead of wrapped.
You can specify the flow direction by setting the value of the
FlowDirection property. The FlowLayoutPanel control correctly reverses
its flow direction in right-to-left (RTL) layouts. You can also
specify whether the contents of the FlowLayoutPanel control are
wrapped or clipped by setting the value of the WrapContents property.
Related
I have created a windows application where the form size is large enough to view.
I want the form to shrink or maximize based on the screen resolution of the display such that the user can view all the controls in a compact way.
I tried the auto size property in the form but that doesn't work. Is there any property in the form which can resolve this issue?
Or do I need to code something else to resolve this issue ?
Thanks
Setting the WindowState = Maximized will cause the window to open to the full extents of the screen resolution. It doesn't matter what that value is, it will match it.
Edit:
From your comments, it sounds like you want what the AutoSize property will accomplish. I updated the form to add some controls and set the AutoSize = True and the AutoSizeMode = GrowAndShrink. Between these three properties, you should be able to get the form to do exactly what you wish. The one thing to pay attention to is the full extents of your controls within the form. From this picture you can see the form during runtime will resize to fit both text boxes while in the editor, I shrunk the form to hide almost everything. Please also note that in the example below, I set the WindowState = Normal.
Inside the form load event, do this:
private void Form_Load(object sender, EventArgs e) {
Rectangle resolutionRect = System.Windows.Forms.Screen.FromControl(this).Bounds;
if (this.Width >= resolutionRect.Width || this.Height >= resolutionRect.Height) {
this.WindowState = FormWindowState.Maximized;
}
}
I have noticed an issue with having a large number of items in a listbox winforms control.
In this simple test case example, I have 120,000 strings added to a listbox. I originally encountered this using a datatable bound to the listbox.DataSource, but it is reproducible this way as well:
listBox.BeginUpdate();
for(int x = 0; x < 120000; x++)
{
listBox.Items.Add(x);
}
listBox.EndUpdate();
When I click and drag the scroll button from the top to the bottom, after I release the mouse, it moves the scroll button to the middle of the scroll bar.
This is a screenshot of where the button lands when I let it go from exactly at / near the bottom (I was precise and did not have the mouse outside of bounds of the scroll bar).
If I now click on the scroll bar button and move it 3/4/ the way down the length of the control, it will now pop back up to around 1/4th the way down the control length.
Has anyone else seen this and is there a known workaround? (I admittedly haven't looked into this next point) does this control have 'virtual modde' dynamic loading options like datagridview which might incidentally get rid of this strange hiccup?
For example if you want to do this when you first load the form setup the property and its virtual size
use a ListView instead of a ListBox
private void Form1_Load(object sender, EventArgs e)
{
listView1.VirtualMode = true;
listView1.VirtualListSize = 12000;
}
IMHO, you are solving the wrong problem. What is the use case for having such a large number of items in your listbox. The general usage for a list box is for the user to select from the listed population. Does your application really expect users to select specific items from such a large list of choices?
You would do your users (and your performance) a favor by providing a better way to narrow down the list for selection.
I noticed that the list box build in vertical scroll bar only can return the index from scroll position up to maximum 65535. If the items added more than this value then will have the scrolling issue. However, Vertical scroll bar control does not have this issue. It can scroll up to maximum of Int32.Max. I just used the vertical scroll bar control instead of the default build in ListBox scroll bar
I add in another vertical scroll bar (vScrollBar1) and place it on right side of the list box to cover its original's list box vertical scroll bar.
Then Add below code for the vertical scroll bar that I create
private void vScrollBar1_Scroll(object sender, ScrollEventArgs e) { listbox.TopIndex =
e.NewValue; }
private void vScrollBar1_MouseEnter(object sender, EventArgs e)
{
vScrollBar1.Maximum = listbox.Items.Count;
}
I've implemented a grid splitter based on a few blog sources that basically allows expand/collapse based on a double click event.
The splitter is in between two columns of a grid that represent a screen layout with a NavigationPanel on the left and a MainContentPanel on the right, with the splitter allowing the NavigationPanel to be collapsed to a minimum width where only icons are displayed.
Is there a way to disable the default behaviour of the grid splitter when it comes to allowing dragging of the splitter and keyboard adjustments?
My current workaround is as follows
Disable keyboard adjustments by setting Focusable to False
Prevent the user "grabbing" the splitter by placing a ToggleButton control overtop of the same as the GridSplitter, thereby having the button intercepting all mouse clicks.
I've got a version where I don't use a ToggleButton at all and just handle the double click event on the GridSplitter but the problem with that is I can't find a way to disable the mouse dragging functionality.
Honestly don't understand why you'd want to do this, but if you really want to disable mouse AND keyboard input, just set IsEnabled to false. As you already discovered, if you only want to disable keyboard input, set Focusable to false- this is what brought me here, trying to figure that out :)
One alternative I've found is to add a handler for the DragDeltaEvent and then mark it as handled.
public class ExtendedGridSplitter : GridSplitter
{
...
public ExtendedGridSplitter()
{
EventManager.RegisterClassHandler(typeof(ExtendedGridSplitter), Thumb.DragDeltaEvent,
new DragDeltaEventHandler(OnDragDelta));
}
...
private void OnDragDelta(object sender, DragDeltaEventArgs e)
{
e.Handled = true;
}
}
And for the keyboard events overriding the handler works similarly
protected override void OnKeyDown(KeyEventArgs e)
{
e.Handled = true;
}
A simple solution which works for me (though not very pretty) is setting the MaxWidth and MinWidth to the same value. In my case I wanted to turn off the use of the splitter when the user selected to close the window and show a "re-appear" icon it in the sidebar.
Unfortunately the MouseWE grippers still light up but they can do nothing.
Am having a problem in scrollviewer.
Scenario:
am having a stack panel inside which having a content, from mouse move of that content am showing a popup to rearrange those content.
issue: when am trying to handle mouse move of that content popup shows and also scrolling happening.
expected behavior: scrolling should not happen while handling mouse move.
i have tried "HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled" it works fine but it sets the scrollviewer to its initial position, means horizontal offset sets to Zero("0")
thanks in advance.
As per our discussion, I think the best route would be to store a class level boolean which will determine whether or not to enable scrolling. You'd have to set this according to your needs (Probably the same place you were modifying the visibility before).
The next step would be to set up some events and properties on your scrollviewer so that you can control whether it scrolls or not. You really only need to modify the constructor of the page holding the scrollviewer, and create a handler for the ManipulationStarted event. The following assumes your control is named Scroll, and that the variable locked is set to true when the control should not scroll:
public MainWindow()
{
InitializeComponent();
Scroller.ManipulationStarted += new EventHandler<ManipulationStartedEventArgs>(scroller_ManipulationStarted);
Scroller.ManipulationMode = ManipulationMode.Control; // Required
}
void scroller_ManipulationStarted(object sender, ManipulationStartedEventArgs e)
{
if (locked)
{
e.Handled = true;
e.Complete();
}
}
I can't seem to figure this out. I have two group boxes on the left side of my form window. When the window is normal size (1000x700), the two boxes are the same. However, when the window is maximized, it ends up looking like this:
What I want is for both the "Log" group box and the tab control to extend down to the bottom of the window. I have tried messing with anchoring, but that just seems to move it and not resize it. Docking fills the whole side. What options do I have here?
Make Log's
Anchor property= Top|Left|Bottom.
Make tab control's
Anchor property = Top|Left|Bottom|Right
If you anchor to the top, it'll move the whole control up and down.
If you anchor to top+bottom, it'll stretch the control so that it grows as the form grows.
You could change the Max property along with the other event changed. Check this:
private void frm_Resize(object sender, EventArgs e)
{
if (this.ParentForm.WindowState == FormWindowState.Normal &&
this.WindowState == FormWindowState.Maximized)
{
this.ParentForm.WindowState = FormWindowState.Maximized;
}
}