I am trying to have an autocomplete feature for a ToolStripTextBox in a C# winform application
It is what I have tried
toolStripTextBox1.AutoCompleteMode = AutoCompleteMode.Suggest;
toolStripTextBox1.AutoCompleteSource = AutoCompleteSource.AllUrl;
But for it to suggest a URL, I should type the URL from the beginning (e.g. http://en.wikipedia.org/wiki/Machine_learn...)
What I look for is something like Firefox autocomplete feature, as I type a title or part of the URL, it shows me the matching URL. For example after I type Machine_learning in the example above, it should suggests http://en.wikipedia.org/wiki/Machine_learning
Any solution please?
By the way, I found this similar question WinForms | C# | AutoComplete in the Middle of a Textbox?, but it gets a custom source (array of string), however I like to use AutoCompleteSource.AllUrl as autocomplete source. Moreover the mentioned link is about a textbox and I can't use it in a toolbar. what I need is a solution fo toolStripTextBox
This is the code I used.
You only need to set AutoCompleteCustomSource.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
namespace System.Windows.Forms
{
/// <summary>
/// The partial auto complete text box.
/// </summary>
/// <remarks>Set only <seealso href="AutoCompleteCustomSource"/></remarks>
public class PartialAutoCompleteTextBox : TextBox
{
/// <summary>
/// Initializes a new instance of the <see cref="PartialAutoCompleteTextBox"/> class.
/// </summary>
public PartialAutoCompleteTextBox()
{
AutoItemWidth = true;
}
/// <summary>
/// Gets or sets a value indicating whether auto item width.
/// </summary>
[DefaultValue(true)]
public bool AutoItemWidth { get; set; }
/// <summary>
/// Gets or sets the drop down list.
/// </summary>
protected ListBox DropDownList { get; set; }
/// <summary>
/// Fire create control.
/// </summary>
protected override void OnCreateControl()
{
base.OnCreateControl();
DropDownList = new ListBox
{
Left = Left,
Top = Top + Height,
Width = Width,
Visible = false,
};
Parent.Controls.Add(DropDownList);
}
/// <summary>
/// Raise an <see cref="System.Windows.Forms.Control.KeyUp" /> event.</summary>
/// <param name="e"><see cref="System.Windows.Forms.KeyEventArgs" />.</param>
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
UpdateDropDown();
}
/// <summary>
/// Raise an <see cref="System.Windows.Forms.Control.KeyDown" /> event.</summary>
/// <param name="e"><see cref="System.Windows.Forms.KeyEventArgs" />.</param>
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
switch (e.KeyCode)
{
case Keys.Tab:
case Keys.Enter:
if (DropDownList.Visible == true)
{
InsertToText(Convert.ToString(DropDownList.SelectedItem));
HideDropDown();
_beforeText = Text;
e.SuppressKeyPress = true;
}
break;
case Keys.Escape:
if (DropDownList.Visible == true)
{
HideDropDown();
}
e.SuppressKeyPress = true;
break;
case Keys.Up:
if (DropDownList.Visible == true)
{
if (DropDownList.SelectedIndex == 0)
{
Focus();
}
else if (DropDownList.SelectedIndex > 0)
{
DropDownList.SelectedIndex--;
}
e.SuppressKeyPress = true;
}
break;
case Keys.Down:
if (DropDownList.Visible == true)
{
if (DropDownList.SelectedIndex < DropDownList.Items.Count - 1)
{
DropDownList.SelectedIndex++;
}
}
else if (e.Modifiers == Keys.Alt)
{
ShowDropDown();
}
break;
}
}
/// <summary>
/// Checks whether the specified key is an input key or a special key that requires preprocessing.
/// </summary>
/// <param name="keyData">The key data.</param>
/// <returns>A bool.</returns>
protected override bool IsInputKey(Keys keyData)
{
switch (keyData)
{
case Keys.Tab:
return DropDownList.Visible = true;
}
return base.IsInputKey(keyData);
}
private void ShowDropDown()
{
DropDownList.Visible = true;
DropDownList.BringToFront();
}
private void HideDropDown()
{
DropDownList.Visible = false;
}
private string _beforeText;
private void UpdateDropDown()
{
if (Text == _beforeText || AutoCompleteCustomSource.Count == 0)
{
return;
}
_beforeText = Text;
var matches = AutoCompleteCustomSource.Cast<string>().Where(x => x.IndexOf(Text, StringComparison.OrdinalIgnoreCase) >= 0).ToArray();
if (matches.Length > 0)
{
ShowDropDown();
DropDownList.SuspendLayout();
DropDownList.Items.Clear();
DropDownList.Items.AddRange(matches);
if (AutoItemWidth == true)
{
SetAutoItemWidth();
}
DropDownList.SelectedIndex = 0;
DropDownList.Height = DropDownList.GetItemHeight(0) * Math.Min(30, matches.Length);
DropDownList.ResumeLayout();
Focus();
}
else
{
HideDropDown();
}
}
private void InsertToText(string selectedItem)
{
Text = selectedItem;
SelectionStart = Text.Length;
}
private void SetAutoItemWidth()
{
using (var graphics = DropDownList.CreateGraphics())
{
var itemWidth = DropDownList.Items.Cast<string>().Min(x => (int)graphics.MeasureString((x) + "_", DropDownList.Font).Width);
DropDownList.Width = Math.Max(DropDownList.Width, itemWidth + 20); // 20 is scrol bar width
}
}
}
}
Related
My code creates multiple buttons with a certain color. When I click a button I want it to change to a HEX color and it works well. The problem is that when I click in another button, I want the previously selected button to go back to the default color scheme.
private void createButtons()
{
foreach (int axis_number in axis_sequence.number)
{
AxisSequence axis = new AxisSequence (axis_number);
axis.MouseLeftButtonDown += new MouseButtonEventHandler (axis_MouseLeftButtonDown);
axis_sequence.Children.Add (axis);
}
}
void axis_MouseLeftButtonDown (object sender, MouseButtonEventArgs e)
{
var converter = new System.Windows.Media.BrushConverter();
var brush_amob_gray = (System.Windows.Media.Brush)converter.ConvertFromString("#515151");
var brush_amob_orange = (System.Windows.Media.Brush)converter.ConvertFromString("#FF8C00");
((AxisSequence)sender).change_canvas = brush_amob_orange;
((AxisSequence)sender).change_text_color = System.Windows.Media.Brushes.Black;
//When I click another button I wanted to all the others to the default Colors.
AXIS SEQUENCE:
public partial class AxisSequence : UserControl
{
/// <summary>
///
/// </summary>
/// <param name="numero_eixo"></param>
public AxisSequence (int numero_eixo)
{
try
{
InitializeComponent();
Value.Content = numero_eixo.ToString();
}
catch (System.Exception ex)
{
System.Windows.MessageBox.Show(ex.ToString());
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public int get_numero_eixo ()
{
return Int32.Parse (Value.Content.ToString());
}
/// <summary>
///
/// </summary>
public System.Windows.Media.Brush change_canvas { get { return canvas.Background; } set { canvas.Background = value; } }
/// <summary>
///
/// </summary>
public System.Windows.Media.Brush change_text_color { get { return Value.Foreground; } set { Value.Foreground = value; } }
}
I want to implement a custom password textbox which will allow me to enter alphanumeric characters but behaves in a way similar to Android EditText control. i.e. I have to display the character entered for a few milliseconds before masking it using "asterix" or any other password character. I should be able to edit/insert/delete any character anywhere in the content.
For this I have implemented this customized textbox. However there are lot of issues I face.
Here, the adminPassword is the field which will contain the actual password text and not the '*' literals.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace PasswordTextbox
{
public class PasswordTextBox : TextBox
{
private readonly Timer timer;
private Char[] adminPassword = new Char[16];
private readonly char DecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator.ToCharArray()[0];
/// <summary>
///
/// </summary>
public PasswordTextBox()
{
timer = new Timer {Interval = 200};
timer.Tick += timer_Tick;
}
/// <summary>
///
/// </summary>
public string AdminPassword
{
get
{
return new string(adminPassword).Trim('\0').Replace("\0", "");
}
}
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
txtInput_TextChanged(this,e);
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtInput_TextChanged(object sender, EventArgs e)
{
HidePasswordCharacters();
}
/// <summary>
///
/// </summary>
private void HidePasswordCharacters()
{
int num = this.Text.Count();
if (num > 1)
{
StringBuilder s = new StringBuilder(this.Text);
s[num - 2] = '*';
this.Text = s.ToString();
this.SelectionStart = num;
timer.Enabled = true;
}
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.KeyCode == Keys.Delete)
{
DeleteSelectedCharacters(this,e.KeyCode);
}
}
/// <summary>
/// Windows Timer elapsed eventhandler
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void timer_Tick(object sender, EventArgs e)
{
timer.Enabled = false;
int num = this.Text.Count();
if (num > 1)
{
StringBuilder s = new StringBuilder(this.Text);
s[num - 1] = '*';
this.Invoke(new Action(() =>
{
this.Text = s.ToString();
this.SelectionStart = num;
}));
}
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
base.OnKeyPress(e);
int selectionStart = this.SelectionStart;
int length = this.TextLength;
int selectedChars = this.SelectionLength;
this.TextChanged -= new System.EventHandler(txtInput_TextChanged);
if (selectedChars == length)
{
/*
* Means complete text selected so clear it before using it
*/
ClearCharBufferPlusTextBox();
}
Keys eModified = (Keys)e.KeyChar;
if (e.KeyChar == DecimalSeparator)
{
e.Handled = true;
}
if ((Keys.Delete != eModified) && (Keys.Back != eModified))
{
if (Keys.Space != eModified)
{
if (e.KeyChar != '-')
{
if (!char.IsLetterOrDigit(e.KeyChar))
{
e.Handled = true;
}
else
{
adminPassword = new string(adminPassword).Insert(selectionStart, e.KeyChar.ToString()).ToCharArray();
}
}
}
else
{
if (this.TextLength == 0)
{
e.Handled = true;
Array.Clear(adminPassword, 0, adminPassword.Length);
}
}
}
else if ((Keys.Back == eModified) || (Keys.Delete == eModified))
{
DeleteSelectedCharacters(this, eModified);
}
/*
* Replace the characters with '*'
*/
HidePasswordCharacters();
this.TextChanged += new System.EventHandler(this.txtInput_TextChanged);
}
/// <summary>
/// Deletes the specific characters in the char array based on the key press action
/// </summary>
/// <param name="sender"></param>
private void DeleteSelectedCharacters(object sender, Keys key)
{
int selectionStart = this.SelectionStart;
int length = this.TextLength;
int selectedChars = this.SelectionLength;
if (selectedChars == length)
{
ClearCharBufferPlusTextBox();
this.TextChanged += new System.EventHandler(this.txtInput_TextChanged);
return;
}
if (selectedChars > 0)
{
int i = selectionStart;
this.Text.Remove(selectionStart, selectedChars);
adminPassword = new string(adminPassword).Remove(selectionStart, selectedChars).ToCharArray();
}
else
{
/*
* Basically this portion of code is to handle the condition
* when the cursor is placed at the start or in the end
*/
if (selectionStart == 0)
{
/*
* Cursor in the beginning, before the first character
* Delete the character only when Del is pressed, No action when Back key is pressed
*/
if (key == Keys.Delete)
{
adminPassword = new string(adminPassword).Remove(0, 1).ToCharArray();
}
}
else if (selectionStart > 0 && selectionStart < length)
{
/*
* Cursor position anywhere in between
* Backspace and Delete have the same effect
*/
if (key == Keys.Back || key == Keys.Delete)
{
adminPassword = new string(adminPassword).Remove(selectionStart, 1).ToCharArray();
}
}
else if (selectionStart == length)
{
/*
* Cursor at the end, after the last character
* Delete the character only when Back key is pressed, No action when Delete key is pressed
*/
if (key == Keys.Back)
{
adminPassword = new string(adminPassword).Remove(selectionStart - 1, 1).ToCharArray();
}
}
}
}
private void ClearCharBufferPlusTextBox()
{
Array.Clear(adminPassword, 0, adminPassword.Length);
this.Clear();
}
}
}
Issue 1. Due to the delay and the timer added to advance the cursor position to the next highest index, I can't seem to insert any text in between or in the beginning.
Issue 2.
During a delete operation. If i select an index position to delete a particular char literal, due to the timer running in the background, the cursor advances to the end (because of the line this.SelectionStart = num;)
Can anyone of you guide me to overcome the above mentioned issues ?
Cheers
VATSAG
I solved the above issue with the help of simple boolean flags.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace PasswordTextbox
{
public class PasswordTextBox : TextBox
{
private readonly Timer timer;
private Char[] adminPassword = new Char[16];
private readonly char DecimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator.ToCharArray()[0];
private int m_iCaretPosition = 0;
private bool canEdit = true;
/// <summary>
///
/// </summary>
public PasswordTextBox()
{
timer = new Timer { Interval = 200 };
timer.Tick += timer_Tick;
}
/// <summary>
///
/// </summary>
public string AdminPassword
{
get
{
return new string(adminPassword).Trim('\0').Replace("\0", "");
}
}
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnTextChanged(EventArgs e)
{
if (canEdit)
{
base.OnTextChanged(e);
txtInput_TextChanged(this, e);
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void txtInput_TextChanged(object sender, EventArgs e)
{
HidePasswordCharacters();
}
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnMouseClick(MouseEventArgs e)
{
base.OnMouseClick(e);
m_iCaretPosition = this.GetCharIndexFromPosition(e.Location);
}
/// <summary>
///
/// </summary>
private void HidePasswordCharacters()
{
int num = this.Text.Count();
if (num > 1)
{
StringBuilder s = new StringBuilder(this.Text);
s[num - 2] = '*';
this.Text = s.ToString();
this.SelectionStart = num;
m_iCaretPosition = num;
timer.Enabled = true;
}
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.KeyCode == Keys.Delete)
{
canEdit = false;
DeleteSelectedCharacters(this, e.KeyCode);
}
}
/// <summary>
/// Windows Timer elapsed eventhandler
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void timer_Tick(object sender, EventArgs e)
{
timer.Enabled = false;
int num = this.Text.Count();
if (num > 1)
{
StringBuilder s = new StringBuilder(this.Text);
s[num - 1] = '*';
this.Invoke(new Action(() =>
{
this.Text = s.ToString();
this.SelectionStart = num;
m_iCaretPosition = num;
}));
}
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
base.OnKeyPress(e);
int selectionStart = this.SelectionStart;
int length = this.TextLength;
int selectedChars = this.SelectionLength;
canEdit = false;
if (selectedChars == length)
{
/*
* Means complete text selected so clear it before using it
*/
ClearCharBufferPlusTextBox();
}
Keys eModified = (Keys)e.KeyChar;
if (e.KeyChar == DecimalSeparator)
{
e.Handled = true;
}
if ((Keys.Delete != eModified) && (Keys.Back != eModified))
{
if (Keys.Space != eModified)
{
if (e.KeyChar != '-')
{
if (!char.IsLetterOrDigit(e.KeyChar))
{
e.Handled = true;
}
else
{
adminPassword = new string(adminPassword).Insert(selectionStart, e.KeyChar.ToString()).ToCharArray();
}
}
}
else
{
if (this.TextLength == 0)
{
e.Handled = true;
Array.Clear(adminPassword, 0, adminPassword.Length);
}
}
}
else if ((Keys.Back == eModified) || (Keys.Delete == eModified))
{
DeleteSelectedCharacters(this, eModified);
}
/*
* Replace the characters with '*'
*/
HidePasswordCharacters();
canEdit = true;
}
/// <summary>
/// Deletes the specific characters in the char array based on the key press action
/// </summary>
/// <param name="sender"></param>
private void DeleteSelectedCharacters(object sender, Keys key)
{
int selectionStart = this.SelectionStart;
int length = this.TextLength;
int selectedChars = this.SelectionLength;
if (selectedChars == length)
{
ClearCharBufferPlusTextBox();
return;
}
if (selectedChars > 0)
{
int i = selectionStart;
this.Text.Remove(selectionStart, selectedChars);
adminPassword = new string(adminPassword).Remove(selectionStart, selectedChars).ToCharArray();
}
else
{
/*
* Basically this portion of code is to handle the condition
* when the cursor is placed at the start or in the end
*/
if (selectionStart == 0)
{
/*
* Cursor in the beginning, before the first character
* Delete the character only when Del is pressed, No action when Back key is pressed
*/
if (key == Keys.Delete)
{
adminPassword = new string(adminPassword).Remove(0, 1).ToCharArray();
}
}
else if (selectionStart > 0 && selectionStart < length)
{
/*
* Cursor position anywhere in between
* Backspace and Delete have the same effect
*/
if (key == Keys.Back || key == Keys.Delete)
{
adminPassword = new string(adminPassword).Remove(selectionStart, 1).ToCharArray();
}
}
else if (selectionStart == length)
{
/*
* Cursor at the end, after the last character
* Delete the character only when Back key is pressed, No action when Delete key is pressed
*/
if (key == Keys.Back)
{
adminPassword = new string(adminPassword).Remove(selectionStart - 1, 1).ToCharArray();
}
}
}
this.Select((selectionStart > this.Text.Length ? this.Text.Length : selectionStart), 0);
}
private void ClearCharBufferPlusTextBox()
{
Array.Clear(adminPassword, 0, adminPassword.Length);
this.Clear();
}
}
}
anyone know how to raise an event on a ListBox when its redrawn. I'm trying to conditionally mask content in one column but the conditional check seems to be done before the listbox has been drawn and so the mask does not work because there is nothing to mask:
/// <summary>
/// Locks or unlocks the quantity textbox based on 100% flour and activates or deactivate weights
/// </summary>
private void activatePieceQuantity()
{
if (isFlour100Percent())
{
((TextBox)NumberOfItemsTextBox as TextBox).IsEnabled = true;
weightsActive(true);
}
else
{
((TextBox)NumberOfItemsTextBox as TextBox).IsEnabled = false;
weightsActive(false);
}
}
/// <summary>
/// Send controls to search with control name and activate or deactivate flag
/// </summary>
/// <param name="activate"></param>
private void weightsActive(bool activate)
{
int locationInList = 0;
foreach (RecipieIngredient ri in activeRecipie.RecipieIngredients)
{
SearchTree(this.IngredientsListBox.ItemContainerGenerator.ContainerFromIndex(locationInList), "QuanityWeight", activate);
locationInList++;
}
}
/// <summary>
/// Find all weight related objects in the ingredients list and set the visibility accordingly
/// </summary>
/// <param name="targetElement"></param>
/// <param name="flagName">Derived from the Tag of the textbox</param>
/// <param name="enableFlag"></param>
private void SearchTree(DependencyObject targetElement, string flagName, bool enableFlag)
{
if (targetElement == null)
return;
var count = VisualTreeHelper.GetChildrenCount(targetElement);
if (count == 0)
return;
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(targetElement, i);
if (child is TextBlock)
{
TextBlock targetItem = (TextBlock)child;
if (targetItem.Name == flagName)
if (enableFlag)
{
((TextBlock)targetItem as TextBlock).Visibility = Visibility.Visible;
return;
}
else
{
((TextBlock)targetItem as TextBlock).Visibility = Visibility.Collapsed;
}
}
else
{
SearchTree(child, flagName, enableFlag);
}
}
}
I got it now, the problem was that the ListBox was not drawn when the SearchTree function was called so there was never any DependencyObject to pass to it.
I solved the problem (somewhat hackish in my opinion) by placing a flag in the code to say that the check had been done and then calling the masking function from a LayoutUpdated event
private void IngredientsListBox_LayoutUpdated(object sender, EventArgs e)
{
if (ingredientsListLoaded)
{
activatePieceQuantity();
ingredientsListLoaded = false;
}
}
I'm extending asp:Repeater to use DataPager, and now my code work with SqlDataSource. To get better performance, I want to use ObjectDataSource with it, but I have to use QueryStringField of DataPager, otherwise I have to click page number twice to make it work. Can any one help on this? this is my code:
namespace WebTest.UserControl
{
public class PageableRepeater : Repeater, IPageableItemContainer
{
private static readonly object EventTotalRowCountAvailable = new object();
private int _startRowIndex = 0;
private int _maximumRows = -1;
private int _totalRowCount = -1;
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page.RegisterRequiresControlState(this);
}
protected override void LoadControlState(object savedState)
{
_startRowIndex = 0;
_maximumRows = -1;
_totalRowCount = -1;
object[] state = savedState as object[];
if (state != null)
{
base.LoadControlState(state[0]);
if (state[1] != null)
{
_totalRowCount = (int)state[1];
}
}
else
{
base.LoadControlState(null);
}
if (!IsViewStateEnabled)
{
OnTotalRowCountAvailable(new PageEventArgs(_startRowIndex, _maximumRows, _totalRowCount));
}
}
protected override object SaveControlState()
{
object baseState = base.SaveControlState();
if (baseState != null || _totalRowCount != -1)
{
object[] state = new object[2];
state[0] = baseState;
state[1] = _totalRowCount;
return state;
}
return true;
}
protected override System.Collections.IEnumerable GetData()
{
ListViewPagedDataSource pagedDataSource = new ListViewPagedDataSource();
pagedDataSource.StartRowIndex = _startRowIndex;
pagedDataSource.MaximumRows = _maximumRows;
if (DataSource is ObjectDataSource)
{
SelectArguments.StartRowIndex = _startRowIndex;
SelectArguments.MaximumRows = _maximumRows;
SelectArguments.RetrieveTotalRowCount = true;
pagedDataSource.DataSource = base.GetData();
_totalRowCount = SelectArguments.TotalRowCount;
pagedDataSource.AllowServerPaging = true;
pagedDataSource.TotalRowCount = _totalRowCount;
}
else
{
pagedDataSource.DataSource = base.GetData();
pagedDataSource.AllowServerPaging = false;
pagedDataSource.TotalRowCount = 0;
_totalRowCount = pagedDataSource.DataSourceCount;
}
return pagedDataSource;
}
protected override void CreateControlHierarchy(bool useDataSource)
{
base.CreateControlHierarchy(useDataSource);
OnTotalRowCountAvailable(new PageEventArgs(_startRowIndex, _maximumRows, _totalRowCount));
}
private void OnTotalRowCountAvailable(PageEventArgs pageEventArgs)
{
EventHandler<PageEventArgs> handler = (EventHandler<PageEventArgs>)Events[EventTotalRowCountAvailable];
if (handler != null)
{
handler(this, pageEventArgs);
}
}
public int MaximumRows
{
get { return _maximumRows; }
}
public int StartRowIndex
{
get { return _startRowIndex; }
}
public void SetPageProperties(int startRowIndex, int maximumRows, bool databind)
{
if (maximumRows < 1)
{
throw new ArgumentOutOfRangeException("maximumRows");
}
if (startRowIndex < 0)
{
throw new ArgumentOutOfRangeException("startRowIndex");
}
_startRowIndex = startRowIndex;
_maximumRows = maximumRows;
if (databind)
{
RequiresDataBinding = true;
}
}
public event EventHandler<PageEventArgs> TotalRowCountAvailable
{
add
{
Events.AddHandler(EventTotalRowCountAvailable, value);
}
remove
{
Events.RemoveHandler(EventTotalRowCountAvailable, value);
}
}
}
}
By the way, I found another implementation to this on CodeProject, but I don't think it use IPageableItemContainer very well.
I know this is an old one, but I've recently been looking for a solution to using the Repeater with a DataPager control.
Most research takes me to this CodeProject article, but it seems like a bit of a hack to me. I've worked on this problem a bit, and put it to the side for a while as I was spinning my wheels on it, until I saw your question and sample code. I was able to take your code and apply it to mine to get a working solution (at least it works for me). With the DataPagerRepeater control below, I'm able to drop the DataPagerRepeater, DataPager, and a DataSource (ObjectDataSource, etc) on the page. Set the DataPagerRepeaters DataSource or DataSourceID to point to the data source, then set the DataPagers PagedControlID to the DataPagerRepeater. Seems to work great.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace My.Web.UI.WebControls
{
/// <summary>
/// Extends the Repeater to be compatable with a DataPager
/// </summary>
/// <remarks>
/// To page through data in a control that implements the IPageableItemContainer interface, DataPager control can be used.
/// Repeater does not support paging and does not implement IPageableItemContainer interface. ListView is the only control that works with DataPager.
///
/// The DataPager control supports built-in paging user interface (UI). NumericPagerField object enables users to select a page of data by page number.
/// NextPreviousPagerField object enables users to move through pages of data one page at a time, or to jump to the first or last page of data.
/// The size of the pages of data is set by using the PageSize property of the DataPager control. One or more pager field objects can be used in
/// a single DataPager control. Custom paging UI can be created by using the TemplatePagerField object. In the TemplatePagerField template,
/// the DataPager control is referenced by using the Container property which provides access to the properties of the DataPager control.
/// These properties include the starting row index, the page size, and the total number of rows currently bound to the control.
/// </remarks>
[ToolboxData("<my:DataPagerRepeater runat=server></my:DataPagerRepeater>")]
[Themeable(true)]
public class DataPagerRepeater : Repeater, IPageableItemContainer
{
/// <summary>Gets the maximum number of items to display on a single page of the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control.
/// </summary>
/// <returns>The maximum number of items to display on a single page of the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control.
/// </returns>
public int MaximumRows
{
get;
//{
// return ViewState["maxrows"] != null ? (int)ViewState["maxrows"] : -1;
//}
private set;
//{
// ViewState["maxrows"] = value;
//}
}
/// <summary>Gets the index of the first record that is displayed on a page of data in the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control.
/// </summary>
/// <returns>The index of the first record that is displayed on a page of data in the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control.
/// </returns>
public int StartRowIndex
{
get;
//{
// return ViewState["startrowindex"] != null ? (int)ViewState["startrowindex"] : -1;
//}
private set;
//{
// ViewState["startrowindex"] = value;
//}
}
/// <summary>
/// Total number of rows that are avialable, regardless of what is currently being displayed
/// </summary>
private int TotalRowsAvailable
{
get;
//{
// return ViewState["totalrows"] != null ? (int)ViewState["totalrows"] : -1;
//}
set;
//{
// ViewState["totalrows"] = value;
//}
}
private static readonly object EventPagePropertiesChanged = new object();
/// <summary>Occurs when the page properties change, after the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control sets the new values.
/// </summary>
public event EventHandler PagePropertiesChanged
{
add
{
base.Events.AddHandler(DataPagerRepeater.EventPagePropertiesChanged, value);
}
remove
{
base.Events.RemoveHandler(DataPagerRepeater.EventPagePropertiesChanged, value);
}
}
private static readonly object EventPagePropertiesChanging = new object();
/// <summary>Occurs when the page properties change, but before the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control sets the new values.
/// </summary>
public event EventHandler<PagePropertiesChangingEventArgs> PagePropertiesChanging
{
add
{
base.Events.AddHandler(DataPagerRepeater.EventPagePropertiesChanging, value);
}
remove
{
base.Events.RemoveHandler(DataPagerRepeater.EventPagePropertiesChanging, value);
}
}
private static readonly object EventTotalRowCountAvailable = new object();
/// <summary>For a description of this member, see <see cref="E:System.Web.UI.WebControls.IPageableItemContainer.TotalRowCountAvailable" />.
/// </summary>
public event EventHandler<PageEventArgs> TotalRowCountAvailable
{
add
{
base.Events.AddHandler(DataPagerRepeater.EventTotalRowCountAvailable, value);
}
remove
{
base.Events.RemoveHandler(DataPagerRepeater.EventTotalRowCountAvailable, value);
}
}
/// <summary>
/// Register the control as one who's control state needs to be persisted
/// </summary>
/// <param name="e"></param>
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page.RegisterRequiresControlState(this);
}
/// <summary>
/// Initialize the start row index, maximum rows, and total rows available values. Load the total rows available from viewstate.
/// </summary>
/// <param name="savedState"></param>
protected override void LoadControlState(object savedState)
{
this.StartRowIndex = 0;
this.MaximumRows = -1;
this.TotalRowsAvailable = -1;
object[] state = savedState as object[];
if (state != null)
{
base.LoadControlState(state[0]);
if (state[1] != null)
{
this.TotalRowsAvailable = (int)state[1];
}
}
else
{
base.LoadControlState(null);
}
if (!IsViewStateEnabled)
{
OnTotalRowCountAvailable(new PageEventArgs(this.StartRowIndex, this.MaximumRows, this.TotalRowsAvailable));
}
}
/// <summary>
/// Save the total rows available value to viewstate
/// </summary>
/// <returns></returns>
protected override object SaveControlState()
{
object baseState = base.SaveControlState();
if (baseState != null || this.TotalRowsAvailable != -1)
{
object[] state = new object[2];
state[0] = baseState;
state[1] = this.TotalRowsAvailable;
return state;
}
return true;
}
/// <summary>Sets the properties of a page of data in the <see cref="T:InteriorHealth.Web.UI.WebControls.DataPagerRepeater" /> control.
/// </summary>
/// <param name="startRowIndex">The index of the first record on the page.</param>
/// <param name="maximumRows">The maximum number of items on a single page.</param>
/// <param name="databind">true to rebind the control after the properties are set; otherwise, false.</param>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="maximumRows" /> is less than 1.-or-<paramref name="startRowIndex" /> is less than 0.
/// </exception>
public void SetPageProperties(int startRowIndex, int maximumRows, bool databind)
{
if (maximumRows < 1)
{
throw new ArgumentOutOfRangeException("maximumRows");
}
if (startRowIndex < 0)
{
throw new ArgumentOutOfRangeException("startRowIndex");
}
if (this.StartRowIndex != startRowIndex || this.StartRowIndex != maximumRows)
{
PagePropertiesChangingEventArgs pagePropertiesChangingEventArgs = new PagePropertiesChangingEventArgs(startRowIndex, maximumRows);
if (databind)
{
this.OnPagePropertiesChanging(pagePropertiesChangingEventArgs);
}
this.StartRowIndex = pagePropertiesChangingEventArgs.StartRowIndex;
this.MaximumRows = pagePropertiesChangingEventArgs.MaximumRows;
if (databind)
{
this.OnPagePropertiesChanged(EventArgs.Empty);
}
}
if (databind)
{
this.RequiresDataBinding = true;
}
//this.OnTotalRowCountAvailable(new PageEventArgs(this.StartRowIndex, this.MaximumRows, this.TotalRowsAvailable));
}
/// <summary>
/// Creates a control hierarchy, with or without the specified data source.
/// </summary>
/// <param name="useDataSource">
/// Indicates whether to use the specified data source.
/// </param>
protected override void CreateControlHierarchy(bool useDataSource)
{
base.CreateControlHierarchy(useDataSource);
OnTotalRowCountAvailable(new PageEventArgs(this.StartRowIndex, this.MaximumRows, this.TotalRowsAvailable));
}
/// <summary>Returns an <see cref="T:System.Collections.IEnumerable" /> interface from the data source.</summary>
/// <returns>An object implementing <see cref="T:System.Collections.IEnumerable" /> that represents the data from the data source.</returns>
protected override System.Collections.IEnumerable GetData()
{
System.Collections.IEnumerable data = base.GetData();
this.TotalRowsAvailable = this.SelectArguments.TotalRowCount;
this.OnTotalRowCountAvailable(new PageEventArgs(this.StartRowIndex, this.MaximumRows, this.TotalRowsAvailable));
return data;
}
/// <summary>Raises the <see cref="E:InteriorHealth.Web.UI.WebControls.DataPagerRepeater.PagePropertiesChanging" /> event.
/// </summary>
/// <param name="e">The event data.</param>
protected virtual void OnPagePropertiesChanging(PagePropertiesChangingEventArgs e)
{
EventHandler<PagePropertiesChangingEventArgs> eventHandler = (EventHandler<PagePropertiesChangingEventArgs>)base.Events[DataPagerRepeater.EventPagePropertiesChanging];
if (eventHandler != null)
{
eventHandler(this, e);
}
}
/// <summary>Raises the <see cref="E:InteriorHealth.Web.UI.WebControls.DataPagerRepeater.SelectedIndexChanged" /> event.</summary>
/// <param name="e">The event data.</param>
protected virtual void OnPagePropertiesChanged(EventArgs e)
{
EventHandler eventHandler = (EventHandler)base.Events[DataPagerRepeater.EventPagePropertiesChanged];
if (eventHandler != null)
{
eventHandler(this, e);
}
}
/// <summary>Raises the <see cref="E:InteriorHealth.Web.UI.WebControls.DataPagerRepeater.PagePropertiesChanging" /> event.</summary>
/// <param name="e">The event data.</param>
protected virtual void OnTotalRowCountAvailable(PageEventArgs e)
{
EventHandler<PageEventArgs> eventHandler = (EventHandler<PageEventArgs>)base.Events[DataPagerRepeater.EventTotalRowCountAvailable];
if (eventHandler != null)
{
eventHandler(this, e);
}
}
/// <summary>
/// Override the selection of rows that we need
/// </summary>
/// <returns></returns>
protected override DataSourceSelectArguments CreateDataSourceSelectArguments()
{
DataSourceSelectArguments arg = base.CreateDataSourceSelectArguments();
arg.StartRowIndex = this.StartRowIndex;
arg.MaximumRows = this.MaximumRows;
return arg;
}
}
}
alt text http://[url=http://www.freeimagehosting.net/][img]http://www.freeimagehosting.net/uploads/06e679a07d.jpg[/img][/url]
How to change the button into image button... the button in the beginning has "Pick a date" when clicked a calender pops out and the when a date is selected a label at the bottom reading the date comes in and the text on the button changes to disabled... i want to palce a imagebutton having a image icon of the calender and rest of the function will be the same....
the code as follows:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
[assembly: TagPrefix("DatePicker", "EWS")]
namespace EclipseWebSolutions.DatePicker
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:DatePicker runat=server>")]
[DefaultEvent("SelectionChanged")]
[ValidationProperty("TextValue")]
public class DatePicker : WebControl, INamingContainer
{
#region Properties
public TextBox txtDate = new TextBox();
public Calendar calDate = new Calendar();
public Button btnDate = new Button();
public Panel pnlCalendar = new Panel();
private enum ViewStateConstants
{
ValidationGroup,
RegularExpression,
ErrorMessage,
RegExText,
CalendarPosition,
FormatString,
ExpandLabel,
CollapseLabel,
ApplyDefaultStyle,
CausesValidation,
}
/// <summary>
/// Defines the available display modes of this calendar.
/// </summary>
public enum CalendarDisplay
{
DisplayRight,
DisplayBelow
}
/// <summary>
/// Where to display the popup calendar.
/// </summary>
[Category("Behaviour")]
[Localizable(true)]
public CalendarDisplay CalendarPosition
{
get
{
if (ViewState[ViewStateConstants.CalendarPosition.ToString()] == null)
{
ViewState[ViewStateConstants.CalendarPosition.ToString()] = CalendarDisplay.DisplayRight;
}
return (CalendarDisplay)ViewState[ViewStateConstants.CalendarPosition.ToString()];
}
set
{
ViewState[ViewStateConstants.CalendarPosition.ToString()] = value;
}
}
/// <summary>
/// Text version of the control's value, for use by ASP.NET validators.
/// </summary>
public string TextValue
{
get { return txtDate.Text; }
}
/// <summary>
/// Holds the current date value of this control.
/// </summary>
[Category("Behaviour")]
[Localizable(true)]
[Bindable(true, BindingDirection.TwoWay)]
public DateTime DateValue
{
get
{
try
{
if (txtDate.Text == "") return DateTime.MinValue;
DateTime val = DateTime.Parse(txtDate.Text);
return val;
}
catch (ArgumentNullException)
{
return DateTime.MinValue;
}
catch (FormatException)
{
return DateTime.MinValue;
}
}
set
{
if (value == DateTime.MinValue)
{
txtDate.Text = "";
}
else
{
txtDate.Text = value.ToShortDateString();
}
}
}
[Category("Behavior"), Themeable(false), DefaultValue("")]
public virtual string ValidationGroup
{
get
{
if (ViewState[ViewStateConstants.ValidationGroup.ToString()] == null)
{
return string.Empty;
}
else
{
return (string)ViewState[ViewStateConstants.ValidationGroup.ToString()];
}
}
set
{
ViewState[ViewStateConstants.ValidationGroup.ToString()] = value;
}
}
/// <summary>
/// The label of the exand button. Shown when the calendar is hidden.
/// </summary>
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("PickDate")]
[Localizable(true)]
public string ExpandButtonLabel
{
get
{
String s = (String)ViewState[ViewStateConstants.ExpandLabel.ToString()];
return ((s == null) ? "PickDate" : s);
}
set
{
ViewState[ViewStateConstants.ExpandLabel.ToString()] = value;
}
}
/// <summary>
/// The label of the collapse button. Shown when the calendar is visible.
/// </summary>
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("Disabled")]
[Localizable(true)]
public string CollapseButtonLabel
{
get
{
String s = (String)ViewState[ViewStateConstants.CollapseLabel.ToString()];
return ((s == null) ? "Disabled" : s);
}
set
{
ViewState[ViewStateConstants.CollapseLabel.ToString()] = value;
}
}
/// <summary>
/// Whether to apply the default style. Disable this if you want to apply a custom style, or to use themes and skins
/// to style the control.
/// </summary>
[Category("Appearance")]
[DefaultValue(true)]
[Localizable(true)]
public bool ApplyDefaultStyle
{
get
{
if (ViewState[ViewStateConstants.ApplyDefaultStyle.ToString()] == null)
{
ViewState[ViewStateConstants.ApplyDefaultStyle.ToString()] = true;
}
return (bool)ViewState[ViewStateConstants.ApplyDefaultStyle.ToString()];
}
set
{
ViewState[ViewStateConstants.ApplyDefaultStyle.ToString()] = value;
}
}
/// <summary>
/// Causes Validation
/// </summary>
[Category("Appearance")]
[DefaultValue(false)]
[Localizable(false)]
public bool CausesValidation
{
get
{
if (ViewState[ViewStateConstants.CausesValidation.ToString()] == null)
{
ViewState[ViewStateConstants.CausesValidation.ToString()] = false;
}
return (bool)ViewState[ViewStateConstants.CausesValidation.ToString()];
}
set
{
ViewState[ViewStateConstants.CausesValidation.ToString()] = value;
btnDate.CausesValidation = value;
}
}
#endregion
#region Events
/// <summary>
/// A day was selected from the calendar control.
/// </summary>
public event EventHandler SelectionChanged;
protected virtual void OnSelectionChanged()
{
if (SelectionChanged != null) // only raise the event if someone is listening.
{
SelectionChanged(this, EventArgs.Empty);
}
}
#endregion
#region Event Handlers
/// <summary>
/// The +/- button was clicked.
/// </summary>
protected void btnDate_Click(object sender, System.EventArgs e)
{
if (!calDate.Visible)
{
// expand the calendar
calDate.Visible = true;
txtDate.Enabled = false;
btnDate.Text = CollapseButtonLabel;
if (DateValue != DateTime.MinValue)
{
calDate.SelectedDate = DateValue;
calDate.VisibleDate = DateValue;
}
}
else
{
// collapse the calendar
calDate.Visible = false;
txtDate.Enabled = true;
btnDate.Text = ExpandButtonLabel;
}
}
/// <summary>
/// A date was selected from the calendar.
/// </summary>
protected void calDate_SelectionChanged(object sender, System.EventArgs e)
{
calDate.Visible = false;
txtDate.Visible = true;
btnDate.Text = ExpandButtonLabel;
txtDate.Enabled = true;
txtDate.Text = calDate.SelectedDate.ToShortDateString();
OnSelectionChanged();
}
#endregion
/// <summary>
/// Builds the contents of this control.
/// </summary>
protected override void CreateChildControls()
{
btnDate.Text = ExpandButtonLabel;
btnDate.CausesValidation = CausesValidation;
txtDate.ID = "txtDate";
calDate.Visible = false;
if (ApplyDefaultStyle)
{
calDate.BackColor = System.Drawing.Color.White;
calDate.BorderColor = System.Drawing.Color.FromArgb(10066329);
calDate.CellPadding = 2;
calDate.DayNameFormat = DayNameFormat.Shortest;
calDate.Font.Name = "Verdana";
calDate.Font.Size = FontUnit.Parse("8pt");
calDate.ForeColor = System.Drawing.Color.Black;
calDate.Height = new Unit(150, UnitType.Pixel);
calDate.Width = new Unit(180, UnitType.Pixel);
calDate.DayHeaderStyle.BackColor = System.Drawing.Color.FromArgb(228, 228, 228);
calDate.DayHeaderStyle.Font.Size = FontUnit.Parse("7pt");
calDate.TitleStyle.Font.Bold = true;
calDate.WeekendDayStyle.BackColor = System.Drawing.Color.FromArgb(255, 255, 204);
}
ConnectEventHandlers();
pnlCalendar.Controls.Add(calDate);
pnlCalendar.Style["position"] = "absolute";
pnlCalendar.Style["filter"] = "alpha(opacity=95)";
pnlCalendar.Style["-moz-opacity"] = ".95";
pnlCalendar.Style["opacity"] = ".95";
pnlCalendar.Style["z-index"] = "2";
pnlCalendar.Style["background-color"] = "White";
if (CalendarPosition == CalendarDisplay.DisplayBelow)
{
pnlCalendar.Style["margin-top"] = "27px";
}
else
{
pnlCalendar.Style["display"] = "inline";
}
Controls.Add(txtDate);
Controls.Add(pnlCalendar);
Controls.Add(btnDate);
base.CreateChildControls();
}
/// <summary>
/// Render the contents of this control.
/// </summary>
/// <param name="output">The HtmlTextWriter to use.</param>
protected override void RenderContents(HtmlTextWriter output)
{
switch (CalendarPosition)
{
case CalendarDisplay.DisplayRight:
{
txtDate.RenderControl(output);
btnDate.RenderControl(output);
pnlCalendar.RenderControl(output);
break;
}
case CalendarDisplay.DisplayBelow:
{
pnlCalendar.RenderControl(output);
txtDate.RenderControl(output);
btnDate.RenderControl(output);
break;
}
}
}
/// <summary>
/// Connect event handlers to events.
/// </summary>
private void ConnectEventHandlers()
{
btnDate.Click += new System.EventHandler(btnDate_Click);
calDate.SelectionChanged += new System.EventHandler(calDate_SelectionChanged);
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
[assembly: TagPrefix("DatePicker", "EWS")]
namespace EclipseWebSolutions.DatePicker
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:DatePicker runat=server>")]
[DefaultEvent("SelectionChanged")]
[ValidationProperty("TextValue")]
public class DatePicker : WebControl, INamingContainer
{
#region Properties
public TextBox txtDate = new TextBox();
public Calendar calDate = new Calendar();
public Button btnDate = new Button();
public Panel pnlCalendar = new Panel();
private enum ViewStateConstants
{
ValidationGroup,
RegularExpression,
ErrorMessage,
RegExText,
CalendarPosition,
FormatString,
ExpandLabel,
CollapseLabel,
ApplyDefaultStyle,
CausesValidation,
}
/// <summary>
/// Defines the available display modes of this calendar.
/// </summary>
public enum CalendarDisplay
{
DisplayRight,
DisplayBelow
}
/// <summary>
/// Where to display the popup calendar.
/// </summary>
[Category("Behaviour")]
[Localizable(true)]
public CalendarDisplay CalendarPosition
{
get
{
if (ViewState[ViewStateConstants.CalendarPosition.ToString()] == null)
{
ViewState[ViewStateConstants.CalendarPosition.ToString()] = CalendarDisplay.DisplayRight;
}
return (CalendarDisplay)ViewState[ViewStateConstants.CalendarPosition.ToString()];
}
set
{
ViewState[ViewStateConstants.CalendarPosition.ToString()] = value;
}
}
/// <summary>
/// Text version of the control's value, for use by ASP.NET validators.
/// </summary>
public string TextValue
{
get { return txtDate.Text; }
}
/// <summary>
/// Holds the current date value of this control.
/// </summary>
[Category("Behaviour")]
[Localizable(true)]
[Bindable(true, BindingDirection.TwoWay)]
public DateTime DateValue
{
get
{
try
{
if (txtDate.Text == "") return DateTime.MinValue;
DateTime val = DateTime.Parse(txtDate.Text);
return val;
}
catch (ArgumentNullException)
{
return DateTime.MinValue;
}
catch (FormatException)
{
return DateTime.MinValue;
}
}
set
{
if (value == DateTime.MinValue)
{
txtDate.Text = "";
}
else
{
txtDate.Text = value.ToShortDateString();
}
}
}
[Category("Behavior"), Themeable(false), DefaultValue("")]
public virtual string ValidationGroup
{
get
{
if (ViewState[ViewStateConstants.ValidationGroup.ToString()] == null)
{
return string.Empty;
}
else
{
return (string)ViewState[ViewStateConstants.ValidationGroup.ToString()];
}
}
set
{
ViewState[ViewStateConstants.ValidationGroup.ToString()] = value;
}
}
/// <summary>
/// The label of the exand button. Shown when the calendar is hidden.
/// </summary>
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("PickDate")]
[Localizable(true)]
public string ExpandButtonLabel
{
get
{
String s = (String)ViewState[ViewStateConstants.ExpandLabel.ToString()];
return ((s == null) ? "PickDate" : s);
}
set
{
ViewState[ViewStateConstants.ExpandLabel.ToString()] = value;
}
}
/// <summary>
/// The label of the collapse button. Shown when the calendar is visible.
/// </summary>
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("Disabled")]
[Localizable(true)]
public string CollapseButtonLabel
{
get
{
String s = (String)ViewState[ViewStateConstants.CollapseLabel.ToString()];
return ((s == null) ? "Disabled" : s);
}
set
{
ViewState[ViewStateConstants.CollapseLabel.ToString()] = value;
}
}
/// <summary>
/// Whether to apply the default style. Disable this if you want to apply a custom style, or to use themes and skins
/// to style the control.
/// </summary>
[Category("Appearance")]
[DefaultValue(true)]
[Localizable(true)]
public bool ApplyDefaultStyle
{
get
{
if (ViewState[ViewStateConstants.ApplyDefaultStyle.ToString()] == null)
{
ViewState[ViewStateConstants.ApplyDefaultStyle.ToString()] = true;
}
return (bool)ViewState[ViewStateConstants.ApplyDefaultStyle.ToString()];
}
set
{
ViewState[ViewStateConstants.ApplyDefaultStyle.ToString()] = value;
}
}
/// <summary>
/// Causes Validation
/// </summary>
[Category("Appearance")]
[DefaultValue(false)]
[Localizable(false)]
public bool CausesValidation
{
get
{
if (ViewState[ViewStateConstants.CausesValidation.ToString()] == null)
{
ViewState[ViewStateConstants.CausesValidation.ToString()] = false;
}
return (bool)ViewState[ViewStateConstants.CausesValidation.ToString()];
}
set
{
ViewState[ViewStateConstants.CausesValidation.ToString()] = value;
btnDate.CausesValidation = value;
}
}
#endregion
#region Events
/// <summary>
/// A day was selected from the calendar control.
/// </summary>
public event EventHandler SelectionChanged;
protected virtual void OnSelectionChanged()
{
if (SelectionChanged != null) // only raise the event if someone is listening.
{
SelectionChanged(this, EventArgs.Empty);
}
}
#endregion
#region Event Handlers
/// <summary>
/// The +/- button was clicked.
/// </summary>
protected void btnDate_Click(object sender, System.EventArgs e)
{
if (!calDate.Visible)
{
// expand the calendar
calDate.Visible = true;
txtDate.Enabled = false;
btnDate.Text = CollapseButtonLabel;
if (DateValue != DateTime.MinValue)
{
calDate.SelectedDate = DateValue;
calDate.VisibleDate = DateValue;
}
}
else
{
// collapse the calendar
calDate.Visible = false;
txtDate.Enabled = true;
btnDate.Text = ExpandButtonLabel;
}
}
/// <summary>
/// A date was selected from the calendar.
/// </summary>
protected void calDate_SelectionChanged(object sender, System.EventArgs e)
{
calDate.Visible = false;
txtDate.Visible = true;
btnDate.Text = ExpandButtonLabel;
txtDate.Enabled = true;
txtDate.Text = calDate.SelectedDate.ToShortDateString();
OnSelectionChanged();
}
#endregion
/// <summary>
/// Builds the contents of this control.
/// </summary>
protected override void CreateChildControls()
{
btnDate.Text = ExpandButtonLabel;
btnDate.CausesValidation = CausesValidation;
txtDate.ID = "txtDate";
calDate.Visible = false;
if (ApplyDefaultStyle)
{
calDate.BackColor = System.Drawing.Color.White;
calDate.BorderColor = System.Drawing.Color.FromArgb(10066329);
calDate.CellPadding = 2;
calDate.DayNameFormat = DayNameFormat.Shortest;
calDate.Font.Name = "Verdana";
calDate.Font.Size = FontUnit.Parse("8pt");
calDate.ForeColor = System.Drawing.Color.Black;
calDate.Height = new Unit(150, UnitType.Pixel);
calDate.Width = new Unit(180, UnitType.Pixel);
calDate.DayHeaderStyle.BackColor = System.Drawing.Color.FromArgb(228, 228, 228);
calDate.DayHeaderStyle.Font.Size = FontUnit.Parse("7pt");
calDate.TitleStyle.Font.Bold = true;
calDate.WeekendDayStyle.BackColor = System.Drawing.Color.FromArgb(255, 255, 204);
}
ConnectEventHandlers();
pnlCalendar.Controls.Add(calDate);
pnlCalendar.Style["position"] = "absolute";
pnlCalendar.Style["filter"] = "alpha(opacity=95)";
pnlCalendar.Style["-moz-opacity"] = ".95";
pnlCalendar.Style["opacity"] = ".95";
pnlCalendar.Style["z-index"] = "2";
pnlCalendar.Style["background-color"] = "White";
if (CalendarPosition == CalendarDisplay.DisplayBelow)
{
pnlCalendar.Style["margin-top"] = "27px";
}
else
{
pnlCalendar.Style["display"] = "inline";
}
Controls.Add(txtDate);
Controls.Add(pnlCalendar);
Controls.Add(btnDate);
base.CreateChildControls();
}
/// <summary>
/// Render the contents of this control.
/// </summary>
/// <param name="output">The HtmlTextWriter to use.</param>
protected override void RenderContents(HtmlTextWriter output)
{
switch (CalendarPosition)
{
case CalendarDisplay.DisplayRight:
{
txtDate.RenderControl(output);
btnDate.RenderControl(output);
pnlCalendar.RenderControl(output);
break;
}
case CalendarDisplay.DisplayBelow:
{
pnlCalendar.RenderControl(output);
txtDate.RenderControl(output);
btnDate.RenderControl(output);
break;
}
}
}
/// <summary>
/// Connect event handlers to events.
/// </summary>
private void ConnectEventHandlers()
{
btnDate.Click += new System.EventHandler(btnDate_Click);
calDate.SelectionChanged += new System.EventHandler(calDate_SelectionChanged);
}
}
}
Untitled Page
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void DatePicker1_SelectionChanged(object sender, EventArgs e)
{
Label1.Text = DatePicker1.DateValue.ToShortDateString();
pnlLabel.Update();
}
}
to make the button an image you could just style it to add a background image.
btnDate.style["background-image"] ="url(images/btn.jpg)";
btnDate.text="";
In Html, an image button has a type attribute of 'image' and a src attribute used to determine the image to be displayed. So, to change a standard button to an image button you would:
buttonControl.Attributes["type"] = "image";
buttonControl.Attributes["src"] = "Foo.jpg";
EDIT
If you are trying to change the button type in the click event, then you might be required to do that via javascript client-side. You can do that by registering a start-up script in the Click event like so:
protected void Button_OnClick( object sender, EventArgs e )
{
var button = sender as Button;
if ( button == null )
return;
var jsScript = new StringBuilder();
jsScript.AppendFormat( "<script type=\"text/javascript\">" );
jsScript.AppendFormat( "var button = document.getElementById(\"{0}\"); button.type = \"image\"; button.src=\"Foo.jpg\";"
, button.ClientID);
jsScript.Append( "</script>" );
if ( !Page.ClientScript.IsStartupScriptRegistered( typeof( Page ), "resetImageButton" ) )
Page.ClientScript.RegisterStartupScript( typeof( Page ), "resetImageButton", jsScript.ToString(), false );
}
The catch is that this will only work right after the postback triggered by clicking the button. It will not survive multiple postbacks. For that, you would need to store a flag in a hidden text field or ViewState that indicates which type the button should be and then, based on that, determine whether you need to register this startup script or not.