|
I just buy the latest O'Reilly "C# X.X in a nutshell" book. Where X.X would seem to be 5.0 on my shelf right now.
|
|
|
|
|
/ravi
|
|
|
|
|
|
Go for LINQ in Action
Fabrice Marguerie, Steve Eichert and Jim Wooley
|
|
|
|
|
Good book LINQ in Action
Fabrice Marguerie, Steve Eichert and Jim Wooley
|
|
|
|
|
|
|
Hi folks,
I have a simple app to look up products, search box, search button, DataGridView to display results and a loading GIF image to show progress.
Initially, I run the query to display results in the grid successfully, but the GIF image will freeze without refreshing.
I was suggested to use threading to run the query on a different thread, I was able to run the query and the GIF image will refresh
However, when using threading, the scrollbars on the grid will not work, I cannot move them at all
If I remove the threading, scrollbars work, but GIF image will not refresh.
Any pointers on what I am doing wrong here?
See the code below for your reference.
Thanks,
...Alex
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace RmsBottleByLocation
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
System.Environment.Exit(0);
}
private void btnSearch_Click(object sender, EventArgs e)
{
lblResults.Text = String.Empty;
grdResults.DataSource = null;
grdResults.Rows.Clear();
grdResults.Refresh();
string keyword = txtKeyword.Text.Trim();
int minimumKeywordLength = Int32.Parse(ConfigurationManager.AppSettings["MinimumKeywordLength"]);
if (keyword.Length < minimumKeywordLength)
{
MessageBox.Show("Please enter item code or item description with at least " + minimumKeywordLength.ToString() + " characters!",
this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtKeyword.SelectAll();
txtKeyword.Focus();
return;
}
loadingImage.Visible = true;
this.Refresh();
runQuery();
}
private void runQuery()
{
string keyword = txtKeyword.Text.Trim();
btnSearch.Enabled = false;
this.Cursor = Cursors.WaitCursor;
string hostName = System.Net.Dns.GetHostName();
string getBottleByLocationStoredProcedure = ConfigurationManager.AppSettings["GetBottleByLocationStoredProcedure"];
string connectionString = ConfigurationManager.AppSettings["ConnectionString"];
string connectionTimeout = ConfigurationManager.AppSettings["ConnectionTimeout"];
connectionString = string.Format(connectionString, hostName);
SqlCommand command = new SqlCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = getBottleByLocationStoredProcedure;
command.CommandTimeout = Int32.Parse(connectionTimeout);
command.Parameters.Add(new SqlParameter("@Keyword", keyword));
try
{
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
command.Connection = connection;
SqlDataReader dr = command.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(dr);
grdResults.DataSource = dt;
grdResults.Columns[0].Width = 500;
grdResults.Columns[0].Frozen = true;
grdResults.Columns[0].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
lblResults.Text = grdResults.Rows.Count.ToString() + " items found!";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
loadingImage.Visible = false;
this.Refresh();
btnSearch.Enabled = true;
this.Cursor = Cursors.Arrow;
}
}
private void grdResults_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
if (e.RowIndex >= 0 && e.ColumnIndex >= 0 && dgv[e.ColumnIndex, e.RowIndex].Value is int)
{
if ((int)dgv[e.ColumnIndex, e.RowIndex].Value == 0)
{
e.Value = "-";
}
}
}
}
}
|
|
|
|
|
You can't just move runQuery into a separate thread - it doesn't work like that.
You can't update display controls from any thread except the one they were created on: the UI thread.
What I would do is use a BackgroundWorker, and use the RunWorkerCompleted event to set the DataSource to the (now complete) DataTable. If that is causing the bottleneck then I'd load each record individually from the DataReader and pass it to the UI thread via the ProgressChanged event (which has a UserState property to the ProgressChangedEventArgs) and add it manually to the display grid.
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
|
You're welcome!
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
Cannot use a leading .. to exit above the top directory.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: Cannot use a leading .. to exit above the top directory.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[HttpException (0x80004005): Cannot use a leading .. to exit above the top directory.]
System.Web.Util.UrlPath.ReduceVirtualPath(String path) +12705512
System.Web.Util.UrlPath.Reduce(String path) +169
System.Web.UI.Control.ResolveClientUrl(String relativeUrl) +314
System.Web.UI.HtmlControls.HtmlLink.RenderAttributes(HtmlTextWriter writer) +172
System.Web.UI.HtmlControls.HtmlLink.Render(HtmlTextWriter writer) +67
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +150
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +249
System.Web.UI.HtmlControls.HtmlHead.RenderChildren(HtmlTextWriter writer) +28
System.Web.UI.HtmlControls.HtmlContainerControl.Render(HtmlTextWriter writer) +49
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +150
System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +249
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +150
System.Web.UI.Control.RenderChildrenInternal(HtmlTex tWriter writer, ICollection children) +249
System.Web.UI.Page.Render(HtmlTextWriter writer) +40
System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +150
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5363
|
|
|
|
|
Without your code? We are guessing...
But teh error is pretty explicit: you are trying to refer to a file directly using a relative path:
..\folder\file.jpg But the current folder is already at the root of the drive (or root of the website for a web app)
Try using an absolute path, or check your current folder is where you think it is!
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
I have a standard ComboBox. Under certain conditions, I would like the background color of the actual ComboBox rectangle (not the drop down list portion) to change. I have found a lot of example on the Internet explaining how to change the color of the items in the drop down list, but this is not what I want. Any ideas?
|
|
|
|
|
Is this Windows Forms, WPF, ASP.NET, or something else?
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
|
You'll need to set the DrawMode property[^] to OwnerDrawFixed or OwnerDrawVariable , depending on whether or not your items have a fixed height.
For OwnerDrawVariable , you'll need to handle the MeasureItem event[^] to specify the size for each item.
You'll then need to handle the DrawItem event[^] to draw each item in the ComboBox . You should be able to identify whether the item is the edit portion of the ComboBox by checking for the DrawItemState.ComboBoxEdit flag in the State property[^] of the DrawItemEventArgs [^].
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Bloody hell, that deserves an up vote just for knowing all the bits!
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
The ComboBox contains plain text so I set DrawMode to OwnerDrawFixed. As far as I understand, the following should work, but it doesn't:
private void comboBox_DrawItem(Object sender, DrawItemEventArgs e)
{
if (e.Index < 0)
{
return;
}
if (e.State == DrawItemState.ComboBoxEdit)
{
e.Graphics.FillRectangle(new SolidBrush(Color.Violet), e.Bounds);
}
else
{
e.Graphics.FillRectangle(new SolidBrush(((ComboBox)sender).BackColor), e.Bounds);
}
e.Graphics.DrawString(((ComboBox)sender).Items[e.Index].ToString(), e.Font,
new SolidBrush(((ComboBox)sender).ForeColor),
new Point(e.Bounds.X, e.Bounds.Y));
e.DrawFocusRectangle();
}
What am I missing?
|
|
|
|
|
It only seem to work if the DropDownStyle is set to DropDownList ; I don't think you can owner-draw the edit box of an editable ComboBox .
The State property can combine multiple values, so you can't do a straight equality test. You'll need to use the HasFlag method[^] instead.
Your code also won't draw anything until you select an item from the list. If you want to see the custom background colour even when you haven't selected an item, you'll need to remove the initial e.Index test, and add a conditional test around the DrawString line:
private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
var control = (ComboBox)sender;
if (e.State.HasFlag(DrawItemState.ComboBoxEdit))
{
e.Graphics.FillRectangle(Brushes.Violet, e.Bounds);
}
else
{
e.DrawBackground();
}
if (e.Index >= 0)
{
e.Graphics.DrawString(control.Items[e.Index].ToString(), e.Font,
new SolidBrush(e.ForeColor), e.Bounds.X, e.Bounds.Y);
}
e.DrawFocusRectangle();
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
e.State.HasFlag gave a compile error so I changed it to:
if (0 < (((int)e.State) & ((int)DrawItemState.ComboBoxEdit)))
There is one strange issue left, though. When I select an item in the ComboBox, the color of the text becomes white. When the ComboBox looses focus, the text becomes black again.
|
|
|
|
|
HasFlag was added in .NET 4.0, so I guess you must be using 3.5 or earlier.
The ForeColor property will change depending on whether or not the item is highlighted. If you always want the text to be black, then use Brushes.Black instead.
private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
var control = (ComboBox)sender;
if (0 != (e.State & DrawItemState.ComboBoxEdit))
{
e.Graphics.FillRectangle(Brushes.Violet, e.Bounds);
if (e.Index >= 0)
{
e.Graphics.DrawString(control.Items[e.Index].ToString(), e.Font,
Brushes.Black, e.Bounds.X, e.Bounds.Y);
}
}
else
{
e.DrawBackground();
if (e.Index >= 0)
{
e.Graphics.DrawString(control.Items[e.Index].ToString(), e.Font,
new SolidBrush(e.ForeColor), e.Bounds.X, e.Bounds.Y);
}
}
e.DrawFocusRectangle();
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Many thanks, it works perfectly now!
|
|
|
|
|
I have a standard ComboBox. As soon as the user "touches" (with the mouse or the keyboard) the ComboBox, I would like to enforce that SelectedValue is never again -1. The normal case is that if the user doesn't select an item, SelectedValue becomes -1. However, if the user doesn't make a selection, I would like the first item to be selected. How can I accomplish this?
|
|
|
|
|
The easiest way is to change the DropDownStyle to DropDownList - then once a value is selected it can never be deselected.
If you combine that with handling the DropDown event and setting the SelectedIndex to zero in that, it should do what you want.
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|