Prevent dropdown of Combo Box collapse before item selected - c#

I want when the button in Pagination is clicked, the dropdown of the Combo Box is still opened, so I can see the result of the pagination in the items of the Combo Box and the dropdown closed when I selected item of Combo Box.
My problem is when I click the buttons in Pagination, the dropdown of the Combo Box closed, so I can't see the result of the pagination.
How to prevent dropdown of Combo Box collapse before item selected in C# Win Form?
CtechComboBoxPagination.cs
using static DiscountCard.View.CustomControl.CtechPagination;
namespace DiscountCard.View.CustomControl
{
public partial class CtechComboBoxPagination : ComboBox
{
public CtechPagination? Pagination { get; set; }
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
public CtechComboBoxPagination()
{
InitializeComponent();
DoubleBuffered = true;
DropDownStyle = ComboBoxStyle.DropDownList;
DrawMode = DrawMode.OwnerDrawFixed;
Font = new Font("Consolas", 11F, FontStyle.Regular, GraphicsUnit.Point);
Pagination = new CtechPagination();
Pagination.SetInitialize(Enumerable.Range(0, 100).AsQueryable(), newContent: true, PaginationPosition.LastPage);
Pagination.FirstPaginationButton_Click += Pagination_FirstPaginationButton_Click;
Pagination.PrevPaginationButton_Click += Pagination_PrevPaginationButton_Click;
Pagination.NextPaginationButton_Click += Pagination_NextPaginationButton_Click;
Pagination.LastPaginationButton_Click += Pagination_LastPaginationButton_Click;
}
private void Pagination_FirstPaginationButton_Click(object? sender, EventArgs e)
{
DroppedDown = true;
}
private void Pagination_PrevPaginationButton_Click(object? sender, EventArgs e)
{
DroppedDown = true;
}
private void Pagination_NextPaginationButton_Click(object? sender, EventArgs e)
{
DroppedDown = true;
}
private void Pagination_LastPaginationButton_Click(object? sender, EventArgs e)
{
DroppedDown = true;
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
e.DrawBackground();
if (e.Index < 0 || e.Index >= Items.Count)
{
return;
}
var item = Items[e.Index];
String? text = item == null ? "(null)" : item.ToString();
TextRenderer.DrawText(e.Graphics, text, e.Font, e.Bounds, e.ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
base.OnDrawItem(e);
}
protected override void OnDropDown(EventArgs e)
{
base.OnDropDown(e);
if (Pagination == null)
{
return;
}
// for test
if (Pagination.CurrentPage != null)
{
Items.Clear();
for (int i = Pagination.CurrentPage.MinIndex; i <= Pagination.CurrentPage.MaxIndex; i++)
{
Items.Add(i);
}
}
Pagination.Margin = new Padding(0);
Pagination.MinimumSize = new Size(this.Width, 30);
ToolStripControlHost host = new ToolStripControlHost(Pagination);
host.Padding = new Padding(0);
ToolStripDropDown dropdown = new ToolStripDropDown();
dropdown.Padding = new Padding(0);
dropdown.Items.Add(host);
if (this.Items.Count > 0)
{
dropdown.Show(this, 0, 3 + this.Height + (this.Items.Count * this.ItemHeight));
}
}
}
}
CtechPagination.cs
using CardData.Ext.Mod.Logger;
using DiscountCard.Ext.Mod.General;
using DiscountCard.View.CustomControl.Pagination;
namespace DiscountCard.View.CustomControl
{
public partial class CtechPagination : UserControl
{
public enum PaginationPosition
{
FirstPage,
PreviousPage,
NextPage,
LastPage,
CurrrentPage
}
public CtechPagination()
{
InitializeComponent();
FirstPaginationButton.Click += OnFirstPaginationButton_Click;
PrevPaginationButton.Click += OnPrevPaginationButton_Click;
NextPaginationButton.Click += OnNextPaginationButton_Click;
LastPaginationButton.Click += OnLastPaginationButton_Click;
}
public event EventHandler? FirstPaginationButton_Click;
public event EventHandler? PrevPaginationButton_Click;
public event EventHandler? NextPaginationButton_Click;
public event EventHandler? LastPaginationButton_Click;
protected virtual void OnFirstPaginationButton_Click(object? sender, EventArgs e)
{
try
{
if (Pages == null)
{
return;
}
if (Pages.Count == 0)
{
return;
}
PageIndex = 0;
Page? firstPage = Pages[PageIndex];
if (firstPage != null)
{
PagesLabel.Text = String.Format("{0:N0} of {1:N0}", firstPage.MinIndex, firstPage.MaxIndex);
FirstPage = firstPage;
CurrentPage = firstPage;
FirstPaginationButton_Click?.Invoke(this, e);
}
}
catch (Exception ex)
{
ExLogger.LogException(ex, "");
}
}
protected virtual void OnPrevPaginationButton_Click(object? sender, EventArgs e)
{
try
{
if (Pages == null)
{
return;
}
if (Pages.Count == 0)
{
return;
}
--PageIndex;
if (PageIndex < 0)
{
PageIndex = 0;
}
Page? prevPage = Pages[PageIndex];
if (prevPage != null)
{
PagesLabel.Text = String.Format("{0:N0} of {1:N0}", prevPage.MinIndex, prevPage.MaxIndex);
PreviousPage = prevPage;
CurrentPage = prevPage;
PrevPaginationButton_Click?.Invoke(this, e);
}
}
catch (Exception ex)
{
ExLogger.LogException(ex, "");
}
}
protected virtual void OnNextPaginationButton_Click(object? sender, EventArgs e)
{
try
{
if (Pages == null)
{
return;
}
if (Pages.Count == 0)
{
return;
}
++PageIndex;
if (PageIndex > Pages.Count - 1)
{
PageIndex = Pages.Count - 1;
}
Page? nextPage = Pages[PageIndex];
if (nextPage != null)
{
PagesLabel.Text = String.Format("{0:N0} of {1:N0}", nextPage.MinIndex, nextPage.MaxIndex);
NextPage = nextPage;
CurrentPage = nextPage;
NextPaginationButton_Click?.Invoke(this, e);
}
}
catch (Exception ex)
{
ExLogger.LogException(ex, "");
}
}
protected virtual void OnLastPaginationButton_Click(object? sender, EventArgs e)
{
try
{
if (Pages == null)
{
return;
}
if (Pages.Count == 0)
{
return;
}
PageIndex = Pages.Count - 1;
Page? lastPage = Pages[PageIndex];
if (lastPage != null)
{
PagesLabel.Text = String.Format("{0:N0} of {1:N0}", lastPage.MinIndex, lastPage.MaxIndex);
LastPage = lastPage;
CurrentPage = lastPage;
LastPaginationButton_Click?.Invoke(this, e);
}
}
catch (Exception ex)
{
ExLogger.LogException(ex, "");
}
}
public void SetInitialize(IQueryable<int> source, bool newContent, PaginationPosition selectedPagination)
{
PageSize = Common.DEFAULT_PAGE_SIZE;
TotalCount = source.Count();
if (TotalCount <= 0)
{
return;
}
TotalPages = (int)Math.Ceiling(TotalCount / (double)PageSize);
if (TotalPages <= 0)
{
return;
}
if (newContent)
{
Pages = new List<Page>();
for (int i = 0; i < TotalPages; i++)
{
IQueryable<int> indexes = (IQueryable<int>)source.Skip(i * PageSize).Take(PageSize);
if (indexes != null)
{
Page page = new Page();
page.MinIndex = 1 + indexes.Min();
page.MaxIndex = 1 + indexes.Max();
Pages.Add(page);
}
}
}
if (Pages != null)
{
switch (selectedPagination)
{
case PaginationPosition.FirstPage:
if (newContent)
{
PageIndex = 0;
}
Page? firstPage = Pages[PageIndex];
if (firstPage != null)
{
PagesLabel.Text = String.Format("{0:N0} of {1:N0}", firstPage.MinIndex, firstPage.MaxIndex);
FirstPage = firstPage;
CurrentPage = firstPage;
}
break;
case PaginationPosition.PreviousPage:
if (newContent)
{
--PageIndex;
}
if (PageIndex < 0)
{
PageIndex = 0;
}
Page? prevPage = Pages[PageIndex];
if (prevPage != null)
{
PagesLabel.Text = String.Format("{0:N0} of {1:N0}", prevPage.MinIndex, prevPage.MaxIndex);
PreviousPage = prevPage;
CurrentPage = prevPage;
}
break;
case PaginationPosition.NextPage:
if (newContent)
{
++PageIndex;
}
if (PageIndex > Pages.Count - 1)
{
PageIndex = Pages.Count - 1;
}
Page? nextPage = Pages[PageIndex];
if (nextPage != null)
{
PagesLabel.Text = String.Format("{0:N0} of {1:N0}", nextPage.MinIndex, nextPage.MaxIndex);
NextPage = nextPage;
CurrentPage = nextPage;
}
break;
case PaginationPosition.LastPage:
if (newContent)
{
PageIndex = Pages.Count - 1;
}
if (PageIndex < 0)
{
PageIndex = 0;
}
Page? lastPage = Pages[PageIndex];
if (lastPage != null)
{
PagesLabel.Text = String.Format("{0:N0} of {1:N0}", lastPage.MinIndex, lastPage.MaxIndex);
LastPage = lastPage;
CurrentPage = lastPage;
}
break;
case PaginationPosition.CurrrentPage:
if (PageIndex < 0)
{
PageIndex = 0;
}
if (PageIndex > Pages.Count - 1)
{
PageIndex = Pages.Count - 1;
}
Page? curentPage = Pages[PageIndex];
if (curentPage != null)
{
PagesLabel.Text = String.Format("{0:N0} of {1:N0}", curentPage.MinIndex, curentPage.MaxIndex);
CurrentPage = curentPage;
}
break;
}
}
}
public int PageIndex { get; private set; }
public int PageSize { get; private set; }
public int TotalCount { get; private set; }
public int TotalPages { get; private set; }
public List<Page>? Pages { get; private set; }
public Page? CurrentPage { get; private set; }
public Page? FirstPage { get; private set; }
public Page? PreviousPage { get; private set; }
public Page? NextPage { get; private set; }
public Page? LastPage { get; private set; }
}
}
CtechPagination.Designer.cs
namespace DiscountCard.View.CustomControl
{
partial class CtechPagination
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.PaginationTableLayoutPanel = new DiscountCard.View.CustomControl.CtechTableLayoutPanel();
this.FirstPaginationButton = new System.Windows.Forms.Button();
this.PrevPaginationButton = new System.Windows.Forms.Button();
this.NextPaginationButton = new System.Windows.Forms.Button();
this.LastPaginationButton = new System.Windows.Forms.Button();
this.PagesLabel = new System.Windows.Forms.Label();
this.PaginationTableLayoutPanel.SuspendLayout();
this.SuspendLayout();
//
// PaginationTableLayoutPanel
//
this.PaginationTableLayoutPanel.ColumnCount = 9;
this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 5F));
this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50F));
this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 5F));
this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50F));
this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50F));
this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 5F));
this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 50F));
this.PaginationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 5F));
this.PaginationTableLayoutPanel.Controls.Add(this.FirstPaginationButton, 1, 0);
this.PaginationTableLayoutPanel.Controls.Add(this.PrevPaginationButton, 3, 0);
this.PaginationTableLayoutPanel.Controls.Add(this.NextPaginationButton, 5, 0);
this.PaginationTableLayoutPanel.Controls.Add(this.LastPaginationButton, 7, 0);
this.PaginationTableLayoutPanel.Controls.Add(this.PagesLabel, 4, 0);
this.PaginationTableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.PaginationTableLayoutPanel.Location = new System.Drawing.Point(0, 0);
this.PaginationTableLayoutPanel.Name = "PaginationTableLayoutPanel";
this.PaginationTableLayoutPanel.RowCount = 1;
this.PaginationTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.PaginationTableLayoutPanel.Size = new System.Drawing.Size(816, 30);
this.PaginationTableLayoutPanel.TabIndex = 0;
//
// FirstPaginationButton
//
this.FirstPaginationButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.FirstPaginationButton.Font = new System.Drawing.Font("Segoe UI", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.FirstPaginationButton.Location = new System.Drawing.Point(8, 3);
this.FirstPaginationButton.Name = "FirstPaginationButton";
this.FirstPaginationButton.Size = new System.Drawing.Size(44, 24);
this.FirstPaginationButton.TabIndex = 0;
this.FirstPaginationButton.Text = "⟨⟨";
this.FirstPaginationButton.UseVisualStyleBackColor = true;
//
// PrevPaginationButton
//
this.PrevPaginationButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.PrevPaginationButton.Font = new System.Drawing.Font("Segoe UI", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.PrevPaginationButton.Location = new System.Drawing.Point(63, 3);
this.PrevPaginationButton.Name = "PrevPaginationButton";
this.PrevPaginationButton.Size = new System.Drawing.Size(44, 24);
this.PrevPaginationButton.TabIndex = 1;
this.PrevPaginationButton.Text = "⟨";
this.PrevPaginationButton.UseVisualStyleBackColor = true;
//
// NextPaginationButton
//
this.NextPaginationButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.NextPaginationButton.Font = new System.Drawing.Font("Segoe UI", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.NextPaginationButton.Location = new System.Drawing.Point(709, 3);
this.NextPaginationButton.Name = "NextPaginationButton";
this.NextPaginationButton.Size = new System.Drawing.Size(44, 24);
this.NextPaginationButton.TabIndex = 2;
this.NextPaginationButton.Text = "⟩";
this.NextPaginationButton.UseVisualStyleBackColor = true;
//
// LastPaginationButton
//
this.LastPaginationButton.Dock = System.Windows.Forms.DockStyle.Fill;
this.LastPaginationButton.Font = new System.Drawing.Font("Segoe UI", 8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.LastPaginationButton.Location = new System.Drawing.Point(764, 3);
this.LastPaginationButton.Name = "LastPaginationButton";
this.LastPaginationButton.Size = new System.Drawing.Size(44, 24);
this.LastPaginationButton.TabIndex = 3;
this.LastPaginationButton.Text = "⟩⟩";
this.LastPaginationButton.UseVisualStyleBackColor = true;
//
// PagesLabel
//
this.PagesLabel.AutoSize = true;
this.PagesLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.PagesLabel.Location = new System.Drawing.Point(113, 0);
this.PagesLabel.Name = "PagesLabel";
this.PagesLabel.Size = new System.Drawing.Size(590, 30);
this.PagesLabel.TabIndex = 4;
this.PagesLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// CtechPagination
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.PaginationTableLayoutPanel);
this.Margin = new System.Windows.Forms.Padding(0);
this.Name = "CtechPagination";
this.Size = new System.Drawing.Size(816, 30);
this.PaginationTableLayoutPanel.ResumeLayout(false);
this.PaginationTableLayoutPanel.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private CtechTableLayoutPanel PaginationTableLayoutPanel;
private Button FirstPaginationButton;
private Button PrevPaginationButton;
private Button NextPaginationButton;
private Button LastPaginationButton;
private Label PagesLabel;
}
}

As I understand it, you've made a UserControl for the pagination and when you click on one of the nav buttons it results in an unwanted close of the drop down.
I was able to reproduce the behavior you're describing and then was able to suppress it by implementing IMessageFilter for the user control in order to intercept the mouse events and mark them as "handled" in the filter (if they occur inside the client rectangle of the UC).
public partial class Pagination : UserControl, IMessageFilter
{
public Pagination()
{
InitializeComponent();
Application.AddMessageFilter(this);
Disposed += (sender, e) =>Application.RemoveMessageFilter(this);
PagesLabel.Text = $"Page {Page} of {Pages}";
}
const int WM_LBUTTONDOWN = 0x0201;
const int WM_LBUTTONUP = 0x0202;
public bool PreFilterMessage(ref Message m)
{
var client = PointToClient(MousePosition);
switch (m.Msg)
{
case WM_LBUTTONDOWN:
if (ClientRectangle.Contains(client))
{
IterateControlTree((control) => hitTest(control, client));
return true;
}
break;
case WM_LBUTTONUP:
if(ClientRectangle.Contains(client))
{
return true;
}
break;
}
return false;
}
.
.
.
}
To be clear, this means no Button.Click events are going to take place either! For this reason it's necessary to iterate the Control tree of the user control to perform a hit test on the button controls it contains.
bool IterateControlTree(Func<Control, bool> action, Control control = null)
{
if (control == null) control = this;
if(action(control)) return true;
foreach (Control child in control.Controls)
{
if(IterateControlTree(action, child))
{
return true;
}
}
return false;
}
For example, detecting a click in the client rectangle of one of the buttons could modify a Page property which in turn fires an event for the combo box to react.
private bool hitTest(Control control, Point client)
{
if (control.Bounds.Contains(client))
{
switch (control.Name)
{
case nameof(FirstPaginationButton): Page = 1; return true;
case nameof(PrevPaginationButton): Page --; return true;
case nameof(NextPaginationButton): Page ++; return true;
case nameof(LastPaginationButton): Page = Pages; return true;
default: break;
}
}
return false;
}
Feel free to browse or clone the code I wrote to test this answer if that would be helpful.

Related

c# New button class "infinite loop error"

I'm currently trying to make a new class named GameButton in Visual Studio Community. im trying to put all the code into it, so that all the code is generated from the button instead of the form, but now that i moved most of the code, it either doesnt show up, or goes into an infinite loop, and im not sure how to fix it at this point. if i didnt give enough information i will supply more if needed.
(Speelveld is a form inside of the form that determines the location of the buttons. The "speelveld" is a Panel imported from the built in toolbox in visual studio. Then the code refrences to that form to build the buttons into.)
Form c#
namespace WindowsFormsApplication9
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Marble();
}
public void Marble()
{
string line;
System.IO.StreamReader file = new System.IO.StreamReader("Bitmap.txt");
int ButtonHeight = 40;
int y_row = 0;
GameButton testButton = new GameButton();
while ((line = file.ReadLine()) != null)
{
for (int x_row = 0; x_row < line.Count(); x_row++)
{
if(line.Substring(x_row, 1) == "1")
{
Speelveld.BackColor = Color.White;
BackColor = Color.White;
testButton.Currentcolor = false;
if (x_row == 4 && y_row == 6)
{
testButton.BackColor = Color.White;
}
else
{
Speelveld.Controls.Add(testButton);
}
}
}
y_row++;
}
}
}
}
GameButton c#
namespace WindowsFormsApplication9
{
public class GameButton: Button
{
public int Row { get; set; }
public int Column { get; set; }
public bool Currentcolor { get; set; }
Pen myPen;
public int ButtonHeight = 40;
public int y_row = 0;
public int x_row = 0;
public void Startup()
{
this.BackColor = Color.Red;
this.Height = ButtonHeight;
this.Width = ButtonHeight;
this.Top = y_row * ButtonHeight + 20;
this.Left = x_row * ButtonHeight + 20;
this.Text = "X: " + x_row.ToString() + " Y: " + y_row.ToString();
this.MouseUp += TmpButton_MouseUp;
}
protected override void OnPaint(PaintEventArgs pevent)
{
int radius = 20;
pevent.Graphics.Clear(Color.White);
Graphics graphics = pevent.Graphics;
myPen = new Pen(new SolidBrush(this.BackColor), 2f);
pevent.Graphics.FillEllipse(new SolidBrush(this.BackColor), 20 - radius, 20 - radius,
radius + radius, radius + radius);
myPen.Dispose();
}
private void TmpButton_MouseUp(object sender, MouseEventArgs e)
{
GameButton Mygamebutton = (GameButton)sender;
Mygamebutton.Currentcolor = !Mygamebutton.Currentcolor;
if (Mygamebutton.Currentcolor == true)
{
Mygamebutton.BackColor = Color.Black;
}
else
{
Mygamebutton.BackColor = Color.White;
}
}
}
}
BitMap.txt
011111110
111111111
111111111
011111110
001111100
000111000
000010000
There are several mistakes in your coed. you didn't call testButton.Startup() to set its position, also the GameButton class needs to know that x_row, y_row values...
please see following:
public void Marble()
{
string line;
System.IO.StreamReader file = new System.IO.StreamReader(#"C:\Users\Main\Desktop\Bitmap.txt");
//var Speelveld = new Form3();
//Speelveld.Show();
int y_row = 0;
while ((line = file.ReadLine()) != null)
{
for (int x_row = 0; x_row < line.Count(); x_row++)
{
if (line.Substring(x_row, 1) == "1")
{
Speelveld.BackColor = Color.White;
BackColor = Color.White;
GameButton testButton = new GameButton(); // ***
testButton.Currentcolor = false;
if (x_row == 4 && y_row == 6)
{
testButton.BackColor = Color.White;
}
else
{
Speelveld.Controls.Add(testButton);
testButton.Startup(x_row , y_row); //***
}
}
}
y_row++;
}
}
and add these in GameButton startup:
public void Startup(int x, int y) //***
{
this.x_row = x; //***
this.y_row = y; //***
...
}

Detect if the TIFF image is Horizontal or Vertical - C#

Im using WinForms. In my Form i have a picturebox and a next button. I use this picturebox to display tiff images and i use the next button to navigate to the next page. The tiff documents are multipage images. The document I'm trying to view has a horizontal images and a vertical images like the example below. If its horizontal i want to size it (1100, 800), but if its vertical i want to size it (800, 1100). How do i do this? currently this is what i have but its not a good solution.
System.Drawing.Image img = System.Drawing.Image.FromFile(path_lbl.Text);
if (img.Height > img.Width)
{
pictureBox1.Width = 800;
pictureBox1.Height = 1300;
}
else
{
pictureBox1.Width = 1300;
pictureBox1.Height = 800;
}
I currently use this approach but this doesn't work because if the first image is vertical the if-statement will always execute the first condition pictureBox1.size(1300 , 800); With this method, if the next image is horizontal the condition will not ever re-size it horizontally.
Example Tiff image
http://www.filedropper.com/verticalandhorizontal
Quick Test Code
using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;
using System.Windows.Forms;
namespace Demo
{
class TestForm : Form
{
public TestForm()
{
var panel = new Panel { Dock = DockStyle.Top, BorderStyle = BorderStyle.FixedSingle };
openButton = new Button { Text = "Open", Top = 8, Left = 16 };
prevButton = new Button { Text = "Prev", Top = 8, Left = 16 + openButton.Right };
nextButton = new Button { Text = "Next", Top = 8, Left = 16 + prevButton.Right };
path_lbl = new Label { Text = "", Top = 12, Left = 16 + nextButton.Right };
panel.Height = 16 + openButton.Height;
panel.Controls.AddRange(new Control[] { openButton, prevButton, nextButton, path_lbl });
pageViewer = new PictureBox { Dock = DockStyle.Fill, SizeMode = PictureBoxSizeMode.Zoom };
ClientSize = new Size(850, 1100 + panel.Height);
Controls.AddRange(new Control[] { panel, pageViewer });
openButton.Click += OnOpenButtonClick;
prevButton.Click += OnPrevButtonClick;
nextButton.Click += OnNextButtonClick;
Disposed += OnFormDisposed;
UpdatePageInfo();
}
private Button openButton;
private Button prevButton;
private Button nextButton;
private PictureBox pageViewer;
private PageBuffer pageData;
private int currentPage;
private Size pageSize;
public string path;
private Label path_lbl;
private void OnOpenButtonClick(object sender, EventArgs e)
{
using (var dialog = new OpenFileDialog())
{
if (dialog.ShowDialog(this) == DialogResult.OK)
Open(dialog.FileName);
path = dialog.FileName;
}
}
private void OnPrevButtonClick(object sender, EventArgs e)
{
SelectPage(currentPage - 1);
}
private void OnNextButtonClick(object sender, EventArgs e)
{
//var data = PageBuffer.Open(path,Size= new Size(850,1150));
SelectPage(currentPage + 1);
//Debug.WriteLine("Current Size: 1300, 800");
}
private void OnFormDisposed(object sender, EventArgs e)
{
if (pageData != null)
pageData.Dispose();
}
private void Open(string path)
{
var data = PageBuffer.Open(path, new Size(1500, 1500));
pageViewer.Image = null;
if (pageData != null)
pageData.Dispose();
pageData = data;
SelectPage(0);
}
private void SelectPage(int index)
{
pageViewer.Image = pageData.GetPage(index);
currentPage = index;
UpdatePageInfo();
}
private void UpdatePageInfo()
{
prevButton.Enabled = pageData != null && currentPage > 0;
nextButton.Enabled = pageData != null && currentPage < pageData.PageCount - 1;
}
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new TestForm());
}
}
class PageBuffer : IDisposable
{
public const int DefaultCacheSize = 12; //This is how much images it will have in memory
public static PageBuffer Open(string path, Size maxSize, int cacheSize = DefaultCacheSize)
{
return new PageBuffer(File.OpenRead(path), maxSize, cacheSize);
}
private PageBuffer(Stream stream, Size maxSize, int cacheSize)
{
this.stream = stream;
source = Image.FromStream(stream);
pageCount = source.GetFrameCount(FrameDimension.Page);
if (pageCount < 2) return;
pageCache = new Image[Math.Min(pageCount, Math.Max(cacheSize, 5))];
pageSize = source.Size;
if (!maxSize.IsEmpty)
{
float scale = Math.Min((float)maxSize.Width / pageSize.Width, (float)maxSize.Height / pageSize.Height);
pageSize = new Size((int)(pageSize.Width * scale), (int)(pageSize.Height * scale));
}
var worker = new Thread(LoadPages) { IsBackground = true };
worker.Start();
}
private void LoadPages()
{
while (true)
{
lock (syncLock)
{
if (disposed) return;
int index = Array.FindIndex(pageCache, 0, pageCacheSize, p => p == null);
if (index < 0)
Monitor.Wait(syncLock);
else
pageCache[index] = LoadPage(pageCacheStart + index);
}
}
}
private Image LoadPage(int index)
{
source.SelectActiveFrame(FrameDimension.Page, index);
return new Bitmap(source, pageSize);
}
private Stream stream;
private Image source;
private int pageCount;
private Image[] pageCache;
private int pageCacheStart, pageCacheSize;
private object syncLock = new object();
private bool disposed;
private Size pageSize;
public Image Source { get { return source; } }
public int PageCount { get { return pageCount; } }
public Image GetPage(int index)
{
if (disposed) throw new ObjectDisposedException(GetType().Name);
if (PageCount < 2) return Source;
lock (syncLock)
{
AdjustPageCache(index);
int cacheIndex = index - pageCacheStart;
var image = pageCache[cacheIndex];
if (image == null)
image = pageCache[cacheIndex] = LoadPage(index);
return image;
}
}
private void AdjustPageCache(int pageIndex)
{
int start, end;
if ((start = pageIndex - pageCache.Length / 2) <= 0)
end = (start = 0) + pageCache.Length;
else if ((end = start + pageCache.Length) >= PageCount)
start = (end = PageCount) - pageCache.Length;
if (start < pageCacheStart)
{
int shift = pageCacheStart - start;
if (shift >= pageCacheSize)
ClearPageCache(0, pageCacheSize);
else
{
ClearPageCache(pageCacheSize - shift, pageCacheSize);
for (int j = pageCacheSize - 1, i = j - shift; i >= 0; j--, i--)
Exchange(ref pageCache[i], ref pageCache[j]);
}
}
else if (start > pageCacheStart)
{
int shift = start - pageCacheStart;
if (shift >= pageCacheSize)
ClearPageCache(0, pageCacheSize);
else
{
ClearPageCache(0, shift);
for (int j = 0, i = shift; i < pageCacheSize; j++, i++)
Exchange(ref pageCache[i], ref pageCache[j]);
}
}
if (pageCacheStart != start || pageCacheStart + pageCacheSize != end)
{
pageCacheStart = start;
pageCacheSize = end - start;
Monitor.Pulse(syncLock);
}
}
void ClearPageCache(int start, int end)
{
for (int i = start; i < end; i++)
Dispose(ref pageCache[i]);
}
static void Dispose<T>(ref T target) where T : class, IDisposable
{
var value = target;
if (value != null) value.Dispose();
target = null;
}
static void Exchange<T>(ref T a, ref T b) { var c = a; a = b; b = c; }
public void Dispose()
{
if (disposed) return;
lock (syncLock)
{
disposed = true;
if (pageCache != null)
{
ClearPageCache(0, pageCacheSize);
pageCache = null;
}
Dispose(ref source);
Dispose(ref stream);
if (pageCount > 2)
Monitor.Pulse(syncLock);
}
}
}
}

c# how does timeSpan work?

I have a timer, how starts, when the text in a label appears and stop when you click on a button. Now i want to stop the reaktiontime and save it in a list, which i want to sort, so i can give out the fastest and lowest reaktiontime in a label. but in my code every time it shows 00:00:00 in the messagebox :(
public partial class Form1 : Form
{
Random r = new Random();
Random Farbe = new Random();
bool Start_MouseClick;
IList<string> Reaktionszeitliste = new List<string>() {};
IList<Color> myColors = new[] { Color.Red, Color.Blue, Color.Green, Color.White, Color.Yellow };
string[] colors = { "Rot", "Blau", "Grün", "Gelb", "Weiß" };
int Timeleft = 5;
int summe = 0, z;
string Reaktionszeit;
int Zeit;
int Spielzuege = 0;
DateTime Time1;
DateTime Time2;
TimeSpan ts;
private void btnRot_Click(object sender, EventArgs e)
{
Spielzuege = Spielzuege + 1;
timMessung.Stop();
if (Start_MouseClick == true)
{
int summe = 0, z;
lblAnzeige.Text = " ";
while (summe <= 0)
{
z = r.Next(1, 6);
summe = summe + z;
}
lblAnzeige.Text += colors[summe - 1] + "\n";
Zeit = 0;
timMessung.Enabled = true;
if (ckbExtrem.Checked == false)
{
lblAnzeige.ForeColor = myColors[Farbe.Next(myColors.Count)];
}
else
{
lblAnzeige.ForeColor = Color.FromArgb(Farbe.Next(256), Farbe.Next(256), Farbe.Next(256));
}
if (Spielzuege == 15)
{
if (txbPlayer2.Text != "")
{
MessageBox.Show("Spieler 2: Machen Sie sich bereit!");
}
else
{
MessageBox.Show(Convert.ToString(ts));
}
}
}
}
private void txbStart_MouseClick(object sender, MouseEventArgs e)
{
if (txbPlayer1.Text == "" && txbPlayer2.Text == "")
{
MessageBox.Show("Bitte geben Sie Spielername(n) ein!");
}
else
{
timVerzögerung.Enabled = true;
panel1.Visible = false;
lblAnzeige.Text = " ";
txbStart.Visible = false;
textBox1.Visible = false;
Start_MouseClick = true;
while (summe <= 0)
{
z = r.Next(1, 6);
summe = summe + z;
}
}
}
private void timMessung_Tick(object sender, EventArgs e)
{
if (timMessung.Enabled == true)
{
Time1 = DateTime.Now;
}
else
{
Time2 = DateTime.Now;
ts = Time1 - Time2;
int differenceInMilli = ts.Milliseconds;
}
}
In a first run i tried to alter your code so that it should run. But i found so many (coding style) issues within there that i simply wrote a completely new example. It also has some minor issues (e.g. size of buttons; it is possible that a color button occurs twice). But it hopefully shows you how TimeSpan and all the other parts can work together.
The Form1.cs file:
public partial class Form1 : Form
{
private Random _Random;
private List<TimeSpan> _ReactionTimes;
private Stopwatch _Stopwatch;
public Form1()
{
InitializeComponent();
_Stopwatch = new Stopwatch();
_Random = new Random(42);
_ReactionTimes = new List<TimeSpan>();
}
private Button CreateButton(Color color)
{
var button = new Button();
button.Click += OnColorButtonClick;
button.BackColor = color;
button.Text = color.Name;
return button;
}
private Button GetRandomButton()
{
var randomIndex = _Random.Next(0, flowLayoutPanel.Controls.Count);
return (Button)flowLayoutPanel.Controls[randomIndex];
}
private Color GetRandomColor()
{
var randomKnownColor = (KnownColor)_Random.Next((int)KnownColor.AliceBlue, (int)KnownColor.ButtonFace);
return Color.FromKnownColor(randomKnownColor);
}
private void InitializeColorButtons(int numberOfColors)
{
var buttons = Enumerable.Range(1, numberOfColors)
.Select(index => GetRandomColor())
.Select(color => CreateButton(color));
foreach (var button in buttons)
{
flowLayoutPanel.Controls.Add(button);
}
}
private void OnButtonStartClick(object sender, EventArgs e)
{
InitializeColorButtons((int)numericUpDownColors.Value);
StartMeasurement();
}
private void OnColorButtonClick(object sender, EventArgs e)
{
var button = (Button)sender;
if (button.Text != labelColorToClick.Text)
{
errorProviderWrongButton.SetIconPadding(button, -20);
errorProviderWrongButton.SetError(button, "Sorry, wrong button.");
return;
}
StopMeasurement();
_ReactionTimes.Add(_Stopwatch.Elapsed);
UpdateSummary();
}
private void StartMeasurement()
{
buttonStart.Enabled = false;
numericUpDownColors.Enabled = false;
labelColorToClick.Text = GetRandomButton().Text;
_Stopwatch.Reset();
_Stopwatch.Start();
}
private void StopMeasurement()
{
_Stopwatch.Stop();
errorProviderWrongButton.Clear();
flowLayoutPanel.Controls.Clear();
numericUpDownColors.Enabled = true;
buttonStart.Enabled = true;
labelColorToClick.Text = String.Empty;
}
private void UpdateSummary()
{
labelSummary.Text = String.Format("Current: {0:0.000} Minimum: {1:0.000} Maximum: {2:0.000}", _ReactionTimes.Last().TotalSeconds, _ReactionTimes.Min().TotalSeconds, _ReactionTimes.Max().TotalSeconds);
}
}
The Form1.Designer.cs file:
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.flowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel();
this.labelColorToClick = new System.Windows.Forms.Label();
this.buttonStart = new System.Windows.Forms.Button();
this.labelSummaryHeader = new System.Windows.Forms.Label();
this.labelSummary = new System.Windows.Forms.Label();
this.errorProviderWrongButton = new System.Windows.Forms.ErrorProvider(this.components);
this.numericUpDownColors = new System.Windows.Forms.NumericUpDown();
((System.ComponentModel.ISupportInitialize)(this.errorProviderWrongButton)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDownColors)).BeginInit();
this.SuspendLayout();
//
// flowLayoutPanel
//
this.flowLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.flowLayoutPanel.Location = new System.Drawing.Point(12, 41);
this.flowLayoutPanel.Name = "flowLayoutPanel";
this.flowLayoutPanel.Size = new System.Drawing.Size(560, 386);
this.flowLayoutPanel.TabIndex = 0;
//
// labelColorToClick
//
this.labelColorToClick.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.labelColorToClick.Location = new System.Drawing.Point(174, 12);
this.labelColorToClick.Name = "labelColorToClick";
this.labelColorToClick.Size = new System.Drawing.Size(398, 23);
this.labelColorToClick.TabIndex = 1;
this.labelColorToClick.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// buttonStart
//
this.buttonStart.Location = new System.Drawing.Point(93, 12);
this.buttonStart.Name = "buttonStart";
this.buttonStart.Size = new System.Drawing.Size(75, 23);
this.buttonStart.TabIndex = 2;
this.buttonStart.Text = "Start";
this.buttonStart.UseVisualStyleBackColor = true;
this.buttonStart.Click += new System.EventHandler(this.OnButtonStartClick);
//
// labelSummaryHeader
//
this.labelSummaryHeader.Location = new System.Drawing.Point(12, 430);
this.labelSummaryHeader.Name = "labelSummaryHeader";
this.labelSummaryHeader.Size = new System.Drawing.Size(75, 23);
this.labelSummaryHeader.TabIndex = 3;
this.labelSummaryHeader.Text = "Summary:";
this.labelSummaryHeader.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// labelSummary
//
this.labelSummary.Location = new System.Drawing.Point(93, 430);
this.labelSummary.Name = "labelSummary";
this.labelSummary.Size = new System.Drawing.Size(479, 23);
this.labelSummary.TabIndex = 4;
this.labelSummary.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// errorProviderWrongButton
//
this.errorProviderWrongButton.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
this.errorProviderWrongButton.ContainerControl = this;
//
// numericUpDownColors
//
this.numericUpDownColors.Location = new System.Drawing.Point(12, 14);
this.numericUpDownColors.Minimum = new decimal(new int[] {
2,
0,
0,
0});
this.numericUpDownColors.Name = "numericUpDownColors";
this.numericUpDownColors.Size = new System.Drawing.Size(75, 20);
this.numericUpDownColors.TabIndex = 5;
this.numericUpDownColors.Value = new decimal(new int[] {
10,
0,
0,
0});
//
// Form1
//
this.ClientSize = new System.Drawing.Size(584, 462);
this.Controls.Add(this.numericUpDownColors);
this.Controls.Add(this.labelSummary);
this.Controls.Add(this.labelSummaryHeader);
this.Controls.Add(this.buttonStart);
this.Controls.Add(this.labelColorToClick);
this.Controls.Add(this.flowLayoutPanel);
this.Name = "Form1";
((System.ComponentModel.ISupportInitialize)(this.errorProviderWrongButton)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDownColors)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel;
private System.Windows.Forms.Label labelColorToClick;
private System.Windows.Forms.Button buttonStart;
private System.Windows.Forms.Label labelSummaryHeader;
private System.Windows.Forms.Label labelSummary;
private System.Windows.Forms.ErrorProvider errorProviderWrongButton;
private System.Windows.Forms.NumericUpDown numericUpDownColors;
}
I think your problem here is that the resolution of DateTime is less than the intervals that you are trying to measure.
Instead of using DateTime, try the following:
Create a private Stopwatch field called stopwatch.
Stopwatch stopwatch = new Stopwatch();
Then change your tick handler to:
private void timMessung_Tick(object sender, EventArgs e)
{
if (timMessung.Enabled == true)
{
stopwatch.Restart();
}
else
{
ts.stopwatch.Elapsed();
}
}
However, I'm also not sure about your logic to do with when you restart the stopwatch. (Where I put stopwatch.Restart().) Do you really want to keep restarting the stopwatch at that point?
use:
ts = Time1.subtract(Time2);
How to calculate datetime diffrence:
How to calculate hours between 2 different dates in c#

Moving drawn items

I am creating dynamic text fields and storing Position and font etc details in an Arraylist. So for example if I click 3 times on Form I am generating 3 random numbers and showing it on clicked position on form. I have one selector button when it is clicked then adding more text functionality is disabled.
Now after when selector button is clicked and if I click ( MouseDown event) on any text then it should move along mouse until MouseUp event is not fired and place on new drop position.
After hours of struggling and searching I found This Solution, So I saved the position and checked with IsPointOnLine method but still its not draggable.
Thank you for any help.
Update: managed to get foreach on place but its still not dragging the selected element.
Form1.Class
public partial class Form1 : Form
{
private Point mouseDownPosition = new Point(0, 0);
private Point mouseMovePosition = new Point(0, 0);
private int mousePressdDown;
IList drawnItemsList = new List<DrawingData>();
private bool dragging;
private bool isSelectorClicked; // if selector button is clicked
DrawingData draggingText;
Random rnd;
int clicked = 0;
public Form1()
{
InitializeComponent();
this.rnd = new Random();
this.isSelectorClicked = false;
dragging = false;
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
mouseMovePosition = e.Location;
if (e.Button == MouseButtons.Left)
mousePressdDown = 1;
if (isSelectorClicked)
{
foreach (DrawingData a in drawnItemsList)
{
if (a.IsPointOnLine(e.Location, 5))
{
draggingText = a;
dragging = true;
}
}
}
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mouseDownPosition = e.Location;
if (dragging)
{
draggingText.cur = mouseDownPosition;
this.Invalidate();
}
}
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if (mousePressdDown == 1 && isSelectorClicked == false)
{
label1.Text = "X: " + mouseMovePosition.X.ToString();
label2.Text = "Y: " + mouseMovePosition.Y.ToString();
this.Invalidate();
DrawingData a = new DrawingData(mouseMovePosition, mouseDownPosition, rnd.Next().ToString(), FontStyle.Bold, 30, "Candara", Brushes.Blue);
drawnItemsList.Add(a);
this.clicked++;
}
mousePressdDown = 0;
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
if(drawnItemsList.Count != 0)
{
foreach (DrawingData a in drawnItemsList)
{
draw(e.Graphics, a);
}
if (mousePressdDown != 0)
{
draw(e.Graphics, mouseDownPosition, mouseMovePosition, FontStyle.Bold, 30, "Candara", Brushes.Blue);
}
}
}
private void draw(Graphics e, Point mold, Point mcur, FontStyle fontWeight, int fontSize, string fontName, Brush fontColor)
{
Pen p = new Pen(Color.Black, 2);
using (Font useFont = new Font(fontName, fontSize, fontWeight))
{
string header2 = rnd.Next().ToString();
RectangleF header2Rect = new RectangleF();
int moldX = mold.X - 5;
int moldY = mold.Y;
header2Rect.Location = new Point(moldX, moldY);
header2Rect.Size = new Size(600, ((int)e.MeasureString(header2, useFont, 600, StringFormat.GenericTypographic).Height));
e.DrawString(header2, useFont, fontColor, header2Rect);
}
}
private void draw(Graphics e, DrawingData a)
{
Pen p = new Pen(Color.Black, 2);
using (Font useFont = new Font(a.FontName, a.FontSize, a.FontWeight))
{
string header2 = rnd.Next().ToString();
RectangleF header2Rect = new RectangleF();
int moldX = a.old.X - 5;
int moldY = a.old.Y;
header2Rect.Location = new Point(moldX, moldY);
header2Rect.Size = new Size(600, ((int)e.MeasureString(header2, useFont, 600, StringFormat.GenericTypographic).Height));
e.DrawString(a.Rand, useFont, a.FontColor, header2Rect);
}
}
private void Select_button_Click(object sender, EventArgs e)
{
this.isSelectorClicked = true;
}
private void WriteNewText_button_Click(object sender, EventArgs e)
{
this.isSelectorClicked = false;
}
}
DrawingData.Class
[Serializable]
public class DrawingData
{
private Point Start; // mouseDown position
private Point End; // mouseUp poslition
private string randValue; // random data value
private FontStyle fontWeight;
private int fontSize;
private string fontName;
private Brush fontColor;
public DrawingData()
{
Start = new Point(0, 0);
End = new Point(0, 0);
randValue = String.Empty;
fontWeight = FontStyle.Bold;
}
public DrawingData(Point old, Point cur, string rand, FontStyle fs, int fSize, string fName, Brush fColor)
{
Start = old;
End = cur;
randValue = rand;
fontWeight = fs;
fontSize = fSize;
fontName = fName;
fontColor = fColor;
}
public float slope
{
get
{
return (((float)End.Y - (float)Start.Y) / ((float)End.X - (float)Start.X));
}
}
public float YIntercept
{
get
{
return Start.Y - slope * Start.X;
}
}
public bool IsPointOnLine(Point p, int cushion)
{
float temp = (slope * p.X + YIntercept);
if (temp >= (p.Y - cushion) && temp <= (p.Y + cushion))
{
return true;
}
else
{
return false;
}
}
public FontStyle FontWeight
{
get
{
return fontWeight;
}
set
{
fontWeight = value;
}
}
public int FontSize
{
get
{
return fontSize;
}
set
{
fontSize = value;
}
}
public string FontName
{
get
{
return fontName;
}
set
{
fontName = value;
}
}
public Brush FontColor
{
get
{
return fontColor;
}
set
{
fontColor = value;
}
}
public Point old
{
get
{
return Start;
}
set
{
Start = value;
}
}
public Point cur
{
get
{
return End;
}
set
{
End = value;
}
}
public string Rand
{
get
{
return randValue;
}
set
{
randValue = value;
}
}
}
SOLVED: I was missing these lines in my mouse move method:
m.Start = new Point(deltaStart.X + e.Location.X, deltaStart.Y + e.Location.Y);
m.End = new Point(deltaEnd.X + e.Location.X, deltaEnd.Y + e.Location.Y);
You should move stuff in Form1_MouseMove instead of Form1_MouseUp.
Find the element you want to move in the Arraylist and assign it new position.
Redraw the element.
Also you should use IList<DrawingData> instead of ArrayList

Multi column combo box or DataGridCombo Box columns shrinking

I have a multi column combo box.When i use it for the first time then it works fine then
when i clear it and again enter data into it,all the columns shrink and only 1-2 letters are visible from each row. But I want to display the text such as all the letters in the table are visible,like in the first image.
Code:
namespace MultiColumnComboBoxDemo
{
public class MultiColumnComboBox : ComboBox
{
public MultiColumnComboBox()
{
DrawMode = DrawMode.OwnerDrawVariable;
}
public new DrawMode DrawMode
{
get
{
return base.DrawMode;
}
set
{
if (value != DrawMode.OwnerDrawVariable)
{
throw new NotSupportedException("Needs to be DrawMode.OwnerDrawVariable");
}
base.DrawMode = value;
}
}
public new ComboBoxStyle DropDownStyle
{
get
{
return base.DropDownStyle;
}
set
{
if (value == ComboBoxStyle.Simple)
{
throw new NotSupportedException("ComboBoxStyle.Simple not supported");
}
base.DropDownStyle = value;
}
}
protected override void OnDataSourceChanged(EventArgs e)
{
base.OnDataSourceChanged(e);
InitializeColumns();
}
protected override void OnValueMemberChanged(EventArgs e)
{
base.OnValueMemberChanged(e);
InitializeValueMemberColumn();
}
protected override void OnDropDown(EventArgs e)
{
base.OnDropDown(e);
this.DropDownWidth = (int)CalculateTotalWidth();
}
const int columnPadding = 5;
private float[] columnWidths = new float[0];
private String[] columnNames = new String[0];
private int valueMemberColumnIndex = 0;
private void InitializeColumns()
{
PropertyDescriptorCollection propertyDescriptorCollection = DataManager.GetItemProperties();
columnWidths = new float[propertyDescriptorCollection.Count];
columnNames = new String[propertyDescriptorCollection.Count];
for (int colIndex = 0; colIndex < propertyDescriptorCollection.Count; colIndex++)
{
String name = propertyDescriptorCollection[colIndex].Name;
columnNames[colIndex] = name;
}
}
private void InitializeValueMemberColumn()
{
int colIndex = 0;
foreach (String columnName in columnNames)
{
if (String.Compare(columnName, ValueMember, true, CultureInfo.CurrentUICulture) == 0)
{
valueMemberColumnIndex = colIndex;
break;
}
colIndex++;
}
}
private float CalculateTotalWidth()
{
float totWidth = 0;
foreach (int width in columnWidths)
{
totWidth += (width + columnPadding);
}
return totWidth + SystemInformation.VerticalScrollBarWidth;
}
protected override void OnMeasureItem(MeasureItemEventArgs e)
{
base.OnMeasureItem(e);
if (DesignMode)
return;
for (int colIndex = 0; colIndex < columnNames.Length; colIndex++)
{
string item = Convert.ToString(FilterItemOnProperty(Items[e.Index], columnNames[colIndex]));
SizeF sizeF = e.Graphics.MeasureString(item, Font);
columnWidths[colIndex] = Math.Max(columnWidths[colIndex], sizeF.Width);
}
float totWidth = CalculateTotalWidth();
e.ItemWidth = (int)totWidth;
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
base.OnDrawItem(e);
if (DesignMode)
return;
e.DrawBackground();
Rectangle boundsRect = e.Bounds;
int lastRight = 0;
//Shakir
//using (Pen linePen = new Pen(SystemColors.GrayText))
using (Pen linePen = new Pen(Color.Black))
{
using (SolidBrush brush = new SolidBrush(e.ForeColor))
//using (SolidBrush brush = new SolidBrush(BackColor))
{
if (columnNames.Length == 0 && e.Index >=0 )
{
e.Graphics.DrawString(Convert.ToString(Items[e.Index]), Font, brush, boundsRect);
}
else
{
for (int colIndex = 0; colIndex < columnNames.Length; colIndex++)
{
string item = Convert.ToString(FilterItemOnProperty(Items[e.Index], columnNames[colIndex]));
boundsRect.X = lastRight;
boundsRect.Width = (int)columnWidths[colIndex] + columnPadding;
lastRight = boundsRect.Right;
if (colIndex == valueMemberColumnIndex)
{
using (Font boldFont = new Font(Font, FontStyle.Bold))
{
e.Graphics.DrawString(item, boldFont, brush, boundsRect);
}
}
else
{
e.Graphics.DrawString(item, Font, brush, boundsRect);
}
if (colIndex < columnNames.Length - 1)
{
e.Graphics.DrawLine(linePen, boundsRect.Right, boundsRect.Top, boundsRect.Right, boundsRect.Bottom);
}
}
}
}
}
e.DrawFocusRectangle();
}
}
}
This is the code which fills data into the multicolumn combo box:
SupplierDisplay is a DataTable
SupplierMaster is the Table in the database
DBRdRw is class
SupplierDisplay = DbRdRw.SqlDbRead("Select SupplierID, SupplierName From SupplierMaster", "SupplierMaster");//data filled to a datatable
//data loading starts
mcbxSupplier.DataSource = SupplierDisplay;
mcbxSupplier.ValueMember = "SupplierName";
mcbxSupplier.DisplayMember = "SupplierName";//ends
add an empty table when u reload the multicolumn combo box just before the SQL statement
here is the full code
DataTable dummytable = new DataTable;
mcbxSupplier.DataSource = dummytable;
SupplierDisplay = DbRdRw.SqlDbRead("Select SupplierID, SupplierName From SupplierMaster", "SupplierMaster");//data filled to a datatable
//data loading starts
mcbxSupplier.DataSource = SupplierDisplay;
mcbxSupplier.ValueMember = "SupplierName";
mcbxSupplier.DisplayMember = "SupplierName";//ends

Categories