I've not bothered with panels, docking, or anchors. I've simply thrown together a ToolBar control (not ToolStrip) and seem unable to size it.
System.Windows.Forms.ToolBar tb = new System.Windows.Forms.ToolBar();
// Reports 292x28 (approx) if I check width and height
// Basically the width of the form and I assume a default height
tb.Size = new System.Drawing.Size(195, 48);
// Reports 48x48, but does not actually create buttons of that size
// (It reports 48x48 because I'm retrieving 48x48 icons from a ResourceManager (resx))
tb.ButtonSize = new System.Drawing.Size(48, 48); //
The closest thing I found to making my ToolBar taller was:
http://bytes.com/topic/c-sharp/answers/241614-changing-height-toolbar-button
Although it's rather dated. And I didn't understand it. ToolBarButtons don't have Height, Width, or Size properties.
I'm using SharpDevelop, coding completely by hand on Vista, with all the .NET frameworks.
EDIT:
Here is the EXACT code that I am currently using.
#region ImageList/Toolbar
ImageList toolbarImages = new ImageList();
Image wizardToolbarImage = (Bitmap) rm.GetObject("wizard");
Image optionsToolbarImage = (Bitmap) rm.GetObject("configure");
toolbarImages.Images.Add(wizardToolbarImage);
toolbarImages.Images.Add(optionsToolbarImage);
ToolBar toolbarMain = new ToolBar();
toolbarMain.Size = new Size(195, 25); // no effect
ToolBarButton wizardToolbarButton = new ToolBarButton();
ToolBarButton optionsToolbarButton = new ToolBarButton();
wizardToolbarButton.ImageIndex = 0;
wizardToolbarButton.ToolTipText = "Wizard!";
optionsToolbarButton.ImageIndex = 1;
optionsToolbarButton.ToolTipText = "Options!";
toolbarMain.Buttons.Add(wizardToolbarButton);
toolbarMain.Buttons.Add(optionsToolbarButton);
toolbarMain.Appearance = ToolBarAppearance.Normal;
toolbarMain.ButtonSize = new System.Drawing.Size(48, 48); // no effect
toolbarMain.ImageList = toolbarImages;
toolbarMain.ButtonClick += new ToolBarButtonClickEventHandler(toolbarMain_Click);
Controls.Add(toolbarMain);
#endregion
In just about every winforms application I've written, regardless of language or framework, the toolbar could only be made taller by using larger icons.
You can also put the toolstrip inside a Panel and set the Dock property of the tool strip to Fill. And then you can size the Panel to whatever size you need.
Related
I created a PictureBox and load an image into it, and I wanted the pictures to have a maximum size (let's say 250px). Here is the code I'm using at that moment
PictureBox cellPictureBox = new PictureBox();
cellPictureBox.AutoSize = false;
cellPictureBox.Dock = DockStyle.Fill;
cellPictureBox.SizeMode = PictureBoxSizeMode.Zoom;
cellPictureBox.Image = Base64ToImage(data.ToString().Trim());
cellPictureBox.Width = 250;
cellPictureBox.Height = 250;
When I load the first image, it's quite large. When I load a second image, it's automatically scaled down to be very tiny, and the newly loaded image takesthe large size the first image had. This trend continues as I add more rows to my data.
What can I do to help manage the sizing of my images? Making a custom control I've been told is useful, but I don't see what is happening that I have wrong.
To set maximum and minimum sizes, have a look at the following:
PictureBox cellPictureBox = new PictureBox();
cellPictureBox.AutoSize = false;
cellPictureBox.Dock = DockStyle.Fill;
cellPictureBox.SizeMode = PictureBoxSizeMode.Zoom;
cellPictureBox.Image = Base64ToImage(data.ToString().Trim());
cellPictureBox.MinimumSize = new Size(100, 100); // or whatever size you want.
cellPictureBox.MaximumSize = new Size(250, 250);
If you only want to set a limit on one dimension, for example, the width, but the height is allowed to be anything, then use int.MaxValue:
cellPictureBox.MaximumSize = new Size(250, int.MaxValue);
I'm trying to fit image to button perfectly.
But the image is cropped on its right and bottom faces, see attached print screen:
I edited the button as follows:
var l_oStopImage = Image.FromFile(#"C:\Users\AmitL\Downloads\Button-2-stop-icon72p.png");
var l_oStopPic = new Bitmap(l_oStopImage , new Size(btnStopOperation.Width, btnStopOperation.Height));
btnStopOperation.Image = l_oStopPic ;
btnStopOperation.ImageAlign = System.Drawing.ContentAlignment.MiddleCenter;
btnStopOperation.TabStop = false;
btnStopOperation.FlatStyle = FlatStyle.Flat;
btnStopOperation.FlatAppearance.BorderSize = 0;
I also tried to edit the BackgroundImageLayout but none of the ImageLayouts fixed the problem..
Any suggestions?
Thanks in advance
1https://msdn.microsoft.com/en-us/library/system.windows.forms.imagelayout(v=vs.110).aspx
You should use stretch, I suggest in designtime (this is not java where you have to add elements by code):
this.buttonOk.BackColor = System.Drawing.SystemColors.MenuHighlight;
this.buttonOk.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("buttonOk.BackgroundImage")));
this.buttonOk.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.buttonOk.Location = new System.Drawing.Point(475, 15);
this.buttonOk.Name = "buttonOk";
this.buttonOk.Size = new System.Drawing.Size(50, 50);
this.buttonOk.TabIndex = 11;
this.buttonOk.UseVisualStyleBackColor = false;
this.buttonOk.Click += new System.EventHandler(this.buttonOk_Click);
And it will work, done it many times before
I got this code from my own working Form1.Designer.cs but because of that: please use the Visual Studio designer and don't try to write all this code / logic in your constructor or something.
The problem is because you are showing an image with the same size as your button.
When you want an image fit in your button, the width and height of image should be at least 1 point less than your button size. (or in other word, you can set your button width and height 1 point more than the image size).
So you can change your code to this:
var l_oStopPic = new Bitmap(l_oStopImage ,
new Size(btnStopOperation.Width-1, btnStopOperation.Height-1));
I want create manually PictureBox and Label on horizontal Panel, The count of PictureBox and Label on panel Unknown maybe 200 or more or less, I use the below code to do that but i face two troubles first one:
I want add the new object created in the first not in the end for example if i created items "A B C D E" want it add on Panel "E D C B A" want always the new come to first.
Note: Panel width "230" Height "710"
Second trouble:
Currently when i use Panel scroll bar to go down than add new objects find happen big free space between the last object created and the new and if i used scroll again to go down and created new object on panel happen more big free space.
int Right = 50, Top = 0;
// Create Image + Text
PictureBox pbox = new PictureBox();
pbox.Size = new Size(140, 80);
pbox.Location = new Point(Right, Top);
pbox.Image = Image.FromFile("");
Panel1.Controls.Add(pbox);
// Create label
Label lblPlateNOBAR = new System.Windows.Forms.Label();
lblPlateNOBAR.Text = lblPlateNO.Text;
lblPlateNOBAR.Location = new Point(Right + 20, Top + 80);
Panel1.Controls.Add(lblPlateNOBAR);
Top = Top + 150;
In order to make the objects insert into the panel, you'd need to move the controls which already exist in the panel:
int right = 50;
// Create Image + Text
PictureBox pbox = new PictureBox();
pbox.Size = new Size(140, 80);
pbox.Location = new Point(right, 0);
pbox.Image = Image.FromFile("");
// Create label
Label lblPlateNOBAR = new System.Windows.Forms.Label();
lblPlateNOBAR.Text = lblPlateNO.Text;
lblPlateNOBAR.Location = new Point(right + 20, 80);
foreach(var control in Panel1.Controls)
{
control.Top = control.Top + 150;
}
Panel1.Controls.Add(pbox);
Panel1.Controls.Add(lblPlateNOBAR);
I know it might seem that I'm not answering your question, but you can take little time to know my suggestion too. I don't know what you wanna achieve, but when you want to make such a sophisticated program, it's a better practice that you do all the work needed yourself, not relying on Windows Forms Controls. Trying to add, remove, change location of lots of controls will reduce the application performance very much. I suggest that you draw, for example your pictures, yourself, using Graphics and Image objects and Paint event. Also handle things like clicking and selecting pictures by MouseEvents. It might seem a little hard at first, but after you've done this you have far better performance and flexibility. This becomes more important considering you mentioned you wanna place 200 pictures in the panel. This also prevents trouble of flickering that appears when you change position of many controls. It's good to mention that to do scrolling in this case, you can place a Panel inside of a Parent Panel and use AutoScroll feature only for the parent panel to handle scrolling. This way you don't have to care about the scrolling anymore.
I have written the following chunk of code that prints my ListBox perfectly when being sent to a physical printer, however when trying to send it to the XPS printer driver or using the XpsDocumentWriter class (I assume they use the same code under the hood) I receive the following exception:
System.ArgumentException was unhandled by user code
Message=Width and Height must be non-negative.
Source=ReachFramework
StackTrace:
at System.Windows.Xps.Serialization.VisualSerializer.WriteTileBrush(String element, TileBrush brush, Rect bounds)
The exception obviously points to an item not having a correct width/height however I have debugged the code when sending it to the different printers (physical and XPS driver) and I haven't been able to find any differences.
Below is how I create the visual to send to the printer:
private ScrollViewer GeneratePrintableView()
{
ScrollViewer scrollView = new ScrollViewer();
Grid grid = new Grid { Background = Brushes.White, Width = this.myListBox.ActualWidth, Height = this.myListBox.ActualHeight };
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions[0].Height = new GridLength(0, GridUnitType.Auto);
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions[1].Height = new GridLength(0, GridUnitType.Auto);
// Add the title and icon to the top
VisualBrush titleClone = new VisualBrush(this.TitleBar);
var titleRectangle = new Rectangle { Fill = titleClone, Width = this.TitleBar.ActualWidth, Height = this.TitleBar.ActualHeight };
grid.Children.Add(titleRectangle);
Grid.SetRow(titleRectangle, 0);
this.myListBox.Width = this.myListBox.ActualWidth;
this.myListBox.Height = this.myListBox.ActualHeight;
VisualBrush clone = new VisualBrush(this.myListBox) { Stretch = Stretch.None, AutoLayoutContent = true };
var rectangle = new Rectangle { Fill = clone, Width = this.myListBox.ActualWidth, Height = this.myListBox.ActualHeight };
Border border = new Border { Background = Brushes.White, Width = this.myListBox.ActualWidth, Height = this.myListBox.ActualHeight };
border.Child = rectangle;
grid.Children.Add(border);
Grid.SetRow(border, 1);
scrollView.Width = this.myListBox.ActualWidth;
scrollView.Height = this.myListBox.ActualHeight;
scrollView.Content = grid;
scrollView.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
return scrollView;
}
Here is the GetPage override in my DocumentPaginator implementation:
public override DocumentPage GetPage(int pageNumber)
{
Page page = new Page();
double z = 0.0;
this.grid = new Grid();
this.grid.RowDefinitions.Add(new RowDefinition());
this.grid.RowDefinitions[0].Height = new GridLength(0, GridUnitType.Auto);
this.grid.Children.Add(this.printViewer);
Grid.SetRow(this.printViewer, 0);
//Adjusting the vertical scroll offset depending on the page number
if (pageNumber + 1 == 1) //if First Page
{
this.printViewer.ScrollToVerticalOffset(0);
this.printViewer.UpdateLayout();
}
else if (pageNumber + 1 == _verticalPageCount) //if Last Page
{
if (this.printViewer.ScrollableHeight == 0) //If printing only single page and the contents fits only on one page
{
this.printViewer.ScrollToVerticalOffset(0);
this.printViewer.UpdateLayout();
}
else if (this.printViewer.ScrollableHeight <= this.printViewer.Height) //If scrollconentheight is less or equal than scrollheight
{
this.printViewer.Height = this.printViewer.ScrollableHeight;
this.printViewer.ScrollToEnd();
this.printViewer.UpdateLayout();
}
else //if the scrollcontentheight is greater than scrollheight then set the scrollviewer height to be the remainder between scrollcontentheight and scrollheight
{
this.printViewer.Height = (this.printViewer.ScrollableHeight % this.printViewer.Height) + 5;
this.printViewer.ScrollToEnd();
this.printViewer.UpdateLayout();
}
}
else //Other Pages
{
z = z + this.printViewer.Height;
this.printViewer.ScrollToVerticalOffset(z);
this.printViewer.UpdateLayout();
}
page.Content = this.grid; //put the grid into the page
page.Arrange(new Rect(this.originalMargin.Left, this.originalMargin.Top, this.ContentSize.Width, this.ContentSize.Height));
page.UpdateLayout();
return new DocumentPage(page);
}
Interestingly if I change the Fill of rectangle to a Brush instead of clone then I do not receive the exception and the outputted file is the correct size.
I have spent over a day trying to debug why this isn't working and I am hoping that someone out there has either seen a similar issue or is able to point out any mistakes I am making.
Thanks for any responses.
I had to give up finding a solution with VisualBrush. If there is a GroupBox in the Visual for the brush I could never get it to produce a XPS file. It always fails with
System.ArgumentException was unhandled by user code Message=Width and Height must be non-negative. Source=ReachFramework StackTrace: at System.Windows.Xps.Serialization.VisualSerializer.WriteTileBrush(String element, TileBrush brush, Rect bounds)
The workaround was to clone the content that should go in the VisualBrush (Is there an easy/built-in way to get an exact copy (clone) of a XAML element?) and use that directly in a Grid instead of an VisualBrush
Have you checked the value of ActualWidth and ActualHeight of myListBox when the VisualBrush is being created? I don't know from where myListBox comes, but if it is not rendered by the time you are generating your xps document you may run into problems. You can try to manually force the control to render and see if it makes any difference.
I was unable to rectify the problem however using this link Paginated printing of WPF visuals I was able to find a suitable solution to allow printing of complicated visuals within my WPF application.
It's 2016 now and it's still not fixed. The problem is using TileBrush or any descendant type (VisualBrush in your case). If you use absolute mapping, it works, it's the relative mapping that causes the problem. Calculate the final size yourself and set Viewport to this size, ViewportUnits to Absolute. Also make sure you don't use Stretch.
I want to create the image of a dynamically created usercontrol and show it in a window.
I am creating the usercontrol using the Below code .
MyViews.MyViewsUserControl myViewsCanvas = new MyViews.MyViewsUserControl(AllFoundationMyViewsViewModel,item.Id);
//myViewsCanvas.Height = 5;
//myViewsCanvas.Width = 5;
Size size = new Size(50, 50);
myViewsCanvas.Measure(size);
double width = myViewsCanvas.DesiredSize.Width;
double height = myViewsCanvas.DesiredSize.Height;
myViewsCanvas.Arrange(new Rect(new Point(), size));
Then i am creating the image of the myViewsCanvas and adding it to a view box of another usercontrol called _DashBoardUserControl using the below code.
_DashBoardUserControl.Viewbox2.Child = CreateImage(myViewsCanvas);
Then i am adding the _DashBoardUserControl to a window.
UserControls.Controls.PopupWindow popup = new UserControls.Controls.PopupWindow();
popup.PopupContent = _DashBoardUserControl;
popup.ShowDialog();
The problem is, I can only see a portion of the Image. I guess that is because of the measure() and arrange() methods. Can anybody tell me about these methods or what size should i pass to these methods. Do i need to scale down the image? If yes how do i do that?
The easiest way I know of is this:
Viewbox v = new Viewbox();
v.Child = uielem;
uielem.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
v.Measure(uielem.DesiredSize);
v.Arrange(new Rect(new Point(), uielem.DesiredSize));
v.UpdateLayout();
r.Render(v);
where uielem is the element you want to render and r is the RenderTargetBitmap. (v.UpdateLayout might not be needed there, but I'm not sure anymore).