I have an issue with an textbox, once it was to accept just 3 values know i have update it to nvarchar(MAX) I updated the EntityModelDB but still after this i'm receivein an error when i add more than 3 values in my textbox
Here is my code
if (!Regex.Match(item.treatments_code, #"^[A-Z0-9\-]{6}$").Success)
{
ret = false;
errors = errors.Concat(new string[] { language.text003 }).ToArray();
}
Here is my error
An exception of type 'System.ArgumentException' occurred in DGUIGHF.dll but was not handled in user code
Additional information: Invalid code format. 3 character, uppercase letters [A-Z] or numbers [0-9], or minus '-'.
FormTreatments.cs
using DG.Data.Model.Helpers;
using DG.DentneD.Forms.Objects;
using DG.DentneD.Helpers;
using DG.DentneD.Model;
using DG.DentneD.Model.Entity;
using DG.UI.GHF;
using SMcMaster;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
using Zuby.ADGV;
namespace DG.DentneD.Forms
{
public partial class FormTreatments : DGUIGHFForm
{
private DentneDModel _dentnedModel = null;
private TabElement tabElement_tabTreatments = new TabElement();
private TabElement tabElement_tabTreatmentsPrices = new TabElement();
private readonly BoxLoader _boxLoader = null;
/// <summary>
/// Constructor
/// </summary>
public FormTreatments()
{
InitializeComponent();
(new TabOrderManager(this)).SetTabOrder(TabOrderManager.TabScheme.AcrossFirst);
Initialize(Program.uighfApplication);
_dentnedModel = new DentneDModel();
_dentnedModel.LanguageHelper.LoadFromFile(Program.uighfApplication.LanguageFilename);
_boxLoader = new BoxLoader(_dentnedModel);
}
/// <summary>
/// Add components language
/// </summary>
public override void AddLanguageComponents()
{
//main
LanguageHelper.AddComponent(this);
LanguageHelper.AddComponent(treatmentsidDataGridViewTextBoxColumn, this.GetType().Name, "HeaderText");
LanguageHelper.AddComponent(nameDataGridViewTextBoxColumn, this.GetType().Name, "HeaderText");
LanguageHelper.AddComponent(codeDataGridViewTextBoxColumn, this.GetType().Name, "HeaderText");
LanguageHelper.AddComponent(typeDataGridViewTextBoxColumn, this.GetType().Name, "HeaderText");
LanguageHelper.AddComponent(button_export);
//tabTreatments
LanguageHelper.AddComponent(tabPage_tabTreatments);
LanguageHelper.AddComponent(button_tabTreatments_new);
LanguageHelper.AddComponent(button_tabTreatments_edit);
LanguageHelper.AddComponent(button_tabTreatments_delete);
LanguageHelper.AddComponent(button_tabTreatments_save);
LanguageHelper.AddComponent(button_tabTreatments_cancel);
LanguageHelper.AddComponent(treatments_idLabel);
LanguageHelper.AddComponent(treatments_nameLabel);
LanguageHelper.AddComponent(treatments_codeLabel);
LanguageHelper.AddComponent(treatmentstypes_idLabel);
LanguageHelper.AddComponent(treatments_mexpirationLabel);
LanguageHelper.AddComponent(treatments_mexpirationinfoLabel);
LanguageHelper.AddComponent(treatments_priceLabel);
LanguageHelper.AddComponent(treatments_notesLabel);
LanguageHelper.AddComponent(taxes_idLabel);
LanguageHelper.AddComponent(treatments_isunitpriceCheckBox);
LanguageHelper.AddComponent(button_tabTreatments_unsettaxesid);
//tabTreatmentsPrices
LanguageHelper.AddComponent(tabPage_tabTreatmentsPrices);
LanguageHelper.AddComponent(label_tabTreatmentsPrices_filterpriceslists);
LanguageHelper.AddComponent(treatmentspricesidDataGridViewTextBoxColumn, this.GetType().Name, "HeaderText");
LanguageHelper.AddComponent(pricelistDataGridViewTextBoxColumn, this.GetType().Name, "HeaderText");
LanguageHelper.AddComponent(priceDataGridViewTextBoxColumn, this.GetType().Name, "HeaderText");
LanguageHelper.AddComponent(button_tabTreatmentsPrices_new);
LanguageHelper.AddComponent(button_tabTreatmentsPrices_edit);
LanguageHelper.AddComponent(button_tabTreatmentsPrices_delete);
LanguageHelper.AddComponent(button_tabTreatmentsPrices_save);
LanguageHelper.AddComponent(button_tabTreatmentsPrices_cancel);
LanguageHelper.AddComponent(treatmentsprices_idLabel);
LanguageHelper.AddComponent(treatmentspriceslists_idLabel);
LanguageHelper.AddComponent(treatmentsprices_priceLabel);
}
/// <summary>
/// Form language dictionary
/// </summary>
public class FormLanguage : IDGUIGHFLanguage
{
public string exportColumnCode = "Code";
public string exportColumnType = "Type";
public string exportColumnName = "Name";
public string exportColumnPrice = "Price";
public string exportSaveFileDialogTitle = "Save an Excel File";
public string exportErrorMessage = "Error writing file '{0}'.";
public string exportErrorTitle = "Error";
public string exportSuccessMessage = "File created. Do you want to open it with your default application?";
public string exportSuccessTitle = "Open";
}
/// <summary>
/// Form language
/// </summary>
public FormLanguage language = new FormLanguage();
/// <summary>
/// Initialize TabElements
/// </summary>
protected override void InitializeTabElements()
{
//set Readonly OnSetEditingMode for Controls
DisableReadonlyCheckOnSetEditingModeControlCollection.Add(typeof(DataGridView));
DisableReadonlyCheckOnSetEditingModeControlCollection.Add(typeof(AdvancedDataGridView));
//set Main BindingSource
BindingSourceMain = vTreatmentsBindingSource;
GetDataSourceMain = GetDataSource_main;
//set Main TabControl
TabControlMain = tabControl_main;
//set Main Panels
PanelFiltersMain = panel_filters;
PanelListMain = panel_list;
PanelsExtraMain = null;
//set tabTreatments
tabElement_tabTreatments = new TabElement()
{
TabPageElement = tabPage_tabTreatments,
ElementItem = new TabElement.TabElementItem()
{
PanelData = panel_tabTreatments_data,
PanelActions = panel_tabTreatments_actions,
PanelUpdates = panel_tabTreatments_updates,
ParentBindingSourceList = vTreatmentsBindingSource,
GetParentDataSourceList = GetDataSource_main,
BindingSourceEdit = treatmentsBindingSource,
GetDataSourceEdit = GetDataSourceEdit_tabTreatments,
AfterSaveAction = AfterSaveAction_tabTreatments,
AddButton = button_tabTreatments_new,
UpdateButton = button_tabTreatments_edit,
RemoveButton = button_tabTreatments_delete,
SaveButton = button_tabTreatments_save,
CancelButton = button_tabTreatments_cancel,
Add = Add_tabTreatments,
Update = Update_tabTreatments,
Remove = Remove_tabTreatments
}
};
//set tabTreatmentsPrices
tabElement_tabTreatmentsPrices = new TabElement()
{
TabPageElement = tabPage_tabTreatmentsPrices,
ElementListItem = new TabElement.TabElementListItem()
{
PanelFilters = panel_tabTreatmentsPrices_filters,
PanelList = panel_tabTreatmentsPrices_list,
PanelData = panel_tabTreatmentsPrices_data,
PanelActions = panel_tabTreatmentsPrices_actions,
PanelUpdates = panel_tabTreatmentsPrices_updates,
BindingSourceList = vTreatmentsPricesBindingSource,
GetDataSourceList = GetDataSourceList_tabTreatmentsPrices,
BindingSourceEdit = treatmentspricesBindingSource,
GetDataSourceEdit = GetDataSourceEdit_tabTreatmentsPrices,
AfterSaveAction = AfterSaveAction_tabTreatmentsPrices,
AddButton = button_tabTreatmentsPrices_new,
IsAddButtonDefaultClickEventAttached = false,
UpdateButton = button_tabTreatmentsPrices_edit,
RemoveButton = button_tabTreatmentsPrices_delete,
SaveButton = button_tabTreatmentsPrices_save,
CancelButton = button_tabTreatmentsPrices_cancel,
Add = Add_tabTreatmentsPrices,
Update = Update_tabTreatmentsPrices,
Remove = Remove_tabTreatmentsPrices
}
};
//set Elements
TabElements.Add(tabElement_tabTreatments);
TabElements.Add(tabElement_tabTreatmentsPrices);
}
/// <summary>
/// Loader
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void FormTreatments_Load(object sender, EventArgs e)
{
IsBindingSourceLoading = true;
advancedDataGridView_main.SortASC(advancedDataGridView_main.Columns[2]);
advancedDataGridView_main.SortASC(advancedDataGridView_main.Columns[1]);
advancedDataGridView_main.SortASC(advancedDataGridView_main.Columns[3]);
IsBindingSourceLoading = false;
PreloadView();
ReloadView();
}
/// <summary>
/// Preload View
/// </summary>
private void PreloadView()
{
IsBindingSourceLoading = true;
_boxLoader.LoadComboBoxTreatmentsTypes(treatmentstypes_idComboBox);
_boxLoader.LoadComboBoxTreatmentsPricesLists(treatmentspriceslists_idComboBox);
_boxLoader.LoadComboBoxTaxes(taxes_idComboBox);
_boxLoader.LoadComboBoxFilterTreatmentsPricesLists(comboBox_tabTreatmentsPrices_filterPriceslists);
IsBindingSourceLoading = false;
}
/// <summary>
/// Reset all the tab datagrid
/// </summary>
private void ResetTabsDataGrid()
{
IsBindingSourceLoading = true;
advancedDataGridView_tabTreatmentsPrices_list.CleanFilterAndSort();
advancedDataGridView_tabTreatmentsPrices_list.SortASC(advancedDataGridView_tabTreatmentsPrices_list.Columns[1]);
IsBindingSourceLoading = false;
}
/// <summary>
/// Get main list DataSource
/// </summary>
/// <returns></returns>
private object GetDataSource_main()
{
ResetTabsDataGrid();
IEnumerable<VTreatments> vTreatments =
_dentnedModel.Treatments.List().Select(
r => new VTreatments
{
treatments_id = r.treatments_id,
code = r.treatments_code,
type = _dentnedModel.TreatmentsTypes.Find(r.treatmentstypes_id).treatmentstypes_name,
name = r.treatments_name
}).ToList();
return DGDataTableUtils.ToDataTable<VTreatments>(vTreatments);
}
/// <summary>
/// Main list current element changed hanlder
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void vTreatmentsBindingSource_CurrentChanged(object sender, EventArgs e)
{
if (IsBindingSourceLoading)
return;
//get current itme
int treatments_id = -1;
if (vTreatmentsBindingSource.Current != null)
{
treatments_id = (((DataRowView)vTreatmentsBindingSource.Current).Row).Field<int>("treatments_id");
}
//set treatments fields
treatments_mexpirationTextBox.Text = "";
if (treatments_id != -1)
{
treatments treatment = _dentnedModel.Treatments.Find(treatments_id);
treatments_mexpirationTextBox.Text = treatment.treatments_mexpiration.ToString();
}
//reset treatments prices filter
comboBox_tabTreatmentsPrices_filterPriceslists.SelectedIndex = -1;
}
/// <summary>
/// Export click
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button_export_Click(object sender, EventArgs e)
{
string filename = null;
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Excel|*.xls";
saveFileDialog.Title = language.exportSaveFileDialogTitle; ;
saveFileDialog.ShowDialog();
filename = saveFileDialog.FileName;
if (!String.IsNullOrEmpty(filename))
{
Cursor.Current = Cursors.WaitCursor;
DataTable datatable = new DataTable();
datatable.Clear();
datatable.Columns.Add(language.exportColumnCode);
datatable.Columns.Add(language.exportColumnType);
datatable.Columns.Add(language.exportColumnName);
datatable.Columns.Add(language.exportColumnPrice);
foreach (treatmentspriceslists treatmentspriceslist in _dentnedModel.TreatmentsPricesLists.List().OrderBy(r => r.treatmentspriceslists_name))
{
datatable.Columns.Add(language.exportColumnPrice + "-" + treatmentspriceslist.treatmentspriceslists_id);
}
//add datatable columns
foreach (treatments treatment in _dentnedModel.Treatments.List().OrderBy(r => r.treatments_code))
{
DataRow row = datatable.NewRow();
row[language.exportColumnCode] = treatment.treatments_code;
row[language.exportColumnType] = _dentnedModel.TreatmentsTypes.Find(treatment.treatmentstypes_id).treatmentstypes_name;
row[language.exportColumnName] = treatment.treatments_name;
row[language.exportColumnPrice] = treatment.treatments_price;
foreach (treatmentspriceslists treatmentspriceslist in _dentnedModel.TreatmentsPricesLists.List().OrderBy(r => r.treatmentspriceslists_name))
{
Nullable<decimal> price = null;
treatmentsprices treatmentsprice = _dentnedModel.TreatmentsPrices.FirstOrDefault(r => r.treatments_id == treatment.treatments_id && r.treatmentspriceslists_id == treatmentspriceslist.treatmentspriceslists_id);
if (treatmentsprice != null)
{
price = treatmentsprice.treatmentsprices_price;
}
row[language.exportColumnPrice + "-" + treatmentspriceslist.treatmentspriceslists_id] = price;
}
datatable.Rows.Add(row);
}
Cursor.Current = Cursors.Default;
//export to excel
DataSet dataset = new DataSet();
dataset.Tables.Add(datatable);
if (!String.IsNullOrEmpty(filename))
{
try
{
ExcelExporter.CreateWorkbook(filename, dataset);
}
catch
{
MessageBox.Show(String.Format(language.exportErrorMessage, filename), language.exportErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (MessageBox.Show(language.exportSuccessMessage, language.exportSuccessTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes)
{
try
{
Process.Start(filename);
}
catch { }
}
}
}
}
#region tabTreatments
/// <summary>
/// Load the tab DataSource
/// </summary>
/// <returns></returns>
private object GetDataSourceEdit_tabTreatments()
{
return DGUIGHFData.LoadEntityFromCurrentBindingSource<treatments, DentneDModel>(_dentnedModel.Treatments, vTreatmentsBindingSource, new string[] { "treatments_id" });
}
/// <summary>
/// Do actions after Save
/// </summary>
/// <param name="item"></param>
private void AfterSaveAction_tabTreatments(object item)
{
DGUIGHFData.SetBindingSourcePosition<treatments, DentneDModel>(_dentnedModel.Treatments, item, vTreatmentsBindingSource);
}
/// <summary>
/// Add an item
/// </summary>
/// <param name="item"></param>
private void Add_tabTreatments(object item)
{
DGUIGHFData.Add<treatments, DentneDModel>(_dentnedModel.Treatments, item);
//update mexpiration
if (!String.IsNullOrEmpty(treatments_mexpirationTextBox.Text))
((treatments)item).treatments_mexpiration = Convert.ToByte(treatments_mexpirationTextBox.Text);
else
((treatments)item).treatments_mexpiration = null;
}
/// <summary>
/// Update an item
/// </summary>
/// <param name="item"></param>
private void Update_tabTreatments(object item)
{
//update mexpiration
if (!String.IsNullOrEmpty(treatments_mexpirationTextBox.Text))
((treatments)item).treatments_mexpiration = Convert.ToByte(treatments_mexpirationTextBox.Text);
else
((treatments)item).treatments_mexpiration = null;
DGUIGHFData.Update<treatments, DentneDModel>(_dentnedModel.Treatments, item);
}
/// <summary>
/// Remove an item
/// </summary>
/// <param name="item"></param>
private void Remove_tabTreatments(object item)
{
DGUIGHFData.Remove<treatments, DentneDModel>(_dentnedModel.Treatments, item);
}
/// <summary>
/// Unset taxes_id
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button_tabTreatments_unsettaxesid_Click(object sender, EventArgs e)
{
taxes_idComboBox.SelectedIndex = -1;
}
#endregion
#region tabTreatmentsPrices
/// <summary>
/// Get tab list DataSource
/// </summary>
/// <returns></returns>
private object GetDataSourceList_tabTreatmentsPrices()
{
object ret = null;
//get current treatment
int treatments_id = -1;
if (vTreatmentsBindingSource.Current != null)
{
treatments_id = (((DataRowView)vTreatmentsBindingSource.Current).Row).Field<int>("treatments_id");
}
//get treatments
List<treatmentsprices> treatmentspricesl = new List<treatmentsprices>();
if (comboBox_tabTreatmentsPrices_filterPriceslists.SelectedIndex != -1 && comboBox_tabTreatmentsPrices_filterPriceslists.SelectedIndex != 0)
{
int treatmentspriceslists_id = Convert.ToInt32(comboBox_tabTreatmentsPrices_filterPriceslists.SelectedValue);
treatmentspricesl = _dentnedModel.TreatmentsPrices.List(r => r.treatments_id == treatments_id && r.treatmentspriceslists_id == treatmentspriceslists_id).ToList();
}
else
treatmentspricesl = _dentnedModel.TreatmentsPrices.List(r => r.treatments_id == treatments_id).ToList();
IEnumerable<VTreatmentsPrices> vTreatmentsPrices =
treatmentspricesl.Select(
r => new VTreatmentsPrices
{
treatmentsprices_id = r.treatmentsprices_id,
price = (double)r.treatmentsprices_price,
pricelist = _dentnedModel.TreatmentsPricesLists.Find(r.treatmentspriceslists_id).treatmentspriceslists_name
}).ToList();
ret = DGDataTableUtils.ToDataTable<VTreatmentsPrices>(vTreatmentsPrices);
return ret;
}
/// <summary>
/// Load the tab DataSource
/// </summary>
/// <returns></returns>
private object GetDataSourceEdit_tabTreatmentsPrices()
{
return DGUIGHFData.LoadEntityFromCurrentBindingSource<treatmentsprices, DentneDModel>(_dentnedModel.TreatmentsPrices, vTreatmentsPricesBindingSource, new string[] { "treatmentsprices_id" });
}
/// <summary>
/// Do actions after Save
/// </summary>
/// <param name="item"></param>
private void AfterSaveAction_tabTreatmentsPrices(object item)
{
DGUIGHFData.SetBindingSourcePosition<treatmentsprices, DentneDModel>(_dentnedModel.TreatmentsPrices, item, vTreatmentsPricesBindingSource);
}
/// <summary>
/// Add an item
/// </summary>
/// <param name="item"></param>
private void Add_tabTreatmentsPrices(object item)
{
DGUIGHFData.Add<treatmentsprices, DentneDModel>(_dentnedModel.TreatmentsPrices, item);
}
/// <summary>
/// Update an item
/// </summary>
/// <param name="item"></param>
private void Update_tabTreatmentsPrices(object item)
{
DGUIGHFData.Update<treatmentsprices, DentneDModel>(_dentnedModel.TreatmentsPrices, item);
}
/// <summary>
/// Remove an item
/// </summary>
/// <param name="item"></param>
private void Remove_tabTreatmentsPrices(object item)
{
DGUIGHFData.Remove<treatmentsprices, DentneDModel>(_dentnedModel.TreatmentsPrices, item);
}
/// <summary>
/// New tab button handler
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button_tabTreatmentsPrices_new_Click(object sender, EventArgs e)
{
if (vTreatmentsBindingSource.Current != null)
{
if (AddClick(tabElement_tabTreatmentsPrices))
{
((treatmentsprices)treatmentspricesBindingSource.Current).treatments_id = (((DataRowView)vTreatmentsBindingSource.Current).Row).Field<int>("treatments_id");
if (comboBox_tabTreatmentsPrices_filterPriceslists.SelectedIndex != -1 && comboBox_tabTreatmentsPrices_filterPriceslists.SelectedIndex != 0)
{
((treatmentsprices)treatmentspricesBindingSource.Current).treatmentspriceslists_id = Convert.ToInt32(comboBox_tabTreatmentsPrices_filterPriceslists.SelectedValue);
treatmentspriceslists_idComboBox.Enabled = false;
}
treatmentspricesBindingSource.ResetBindings(true);
}
}
}
/// <summary>
/// Treatments prices changed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void comboBox_tabTreatmentsPrices_filterPriceslists_SelectedIndexChanged(object sender, EventArgs e)
{
if (IsBindingSourceLoading)
return;
ReloadTab(tabElement_tabTreatmentsPrices);
}
/// <summary>
/// Treatments lists changed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void treatmentspriceslists_idComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if (IsBindingSourceLoading)
return;
if (treatmentspriceslists_idComboBox.SelectedIndex != -1 && (tabElement_tabTreatmentsPrices.CurrentEditingMode == EditingMode.C || tabElement_tabTreatmentsPrices.CurrentEditingMode == EditingMode.U))
{
int treatments_id = -1;
if (vTreatmentsBindingSource.Current != null)
{
treatments_id = (((DataRowView)vTreatmentsBindingSource.Current).Row).Field<int>("treatments_id");
}
if (treatments_id != -1)
{
treatments treatments = _dentnedModel.Treatments.Find(treatments_id);
treatmentspriceslists treatmentspriceslist = _dentnedModel.TreatmentsPricesLists.Find(treatmentspriceslists_idComboBox.SelectedValue);
if (treatments != null && treatmentspriceslist != null)
{
((treatmentsprices)treatmentspricesBindingSource.Current).treatmentspriceslists_id = treatmentspriceslist.treatmentspriceslists_id;
((treatmentsprices)treatmentspricesBindingSource.Current).treatmentsprices_price = Math.Round(treatments.treatments_price * treatmentspriceslist.treatmentspriceslists_multiplier, 2);
}
treatmentspricesBindingSource.ResetBindings(true);
}
}
}
#endregion
private void button_tabTreatments_save_Click(object sender, EventArgs e)
{
}
private void treatments_codeTextBox_TextChanged(object sender, EventArgs e)
{
}
}
}
I would suggest reading up on Regular Expressions and download a Regex tool such as Expresso (http://www.ultrapico.com/expresso.htm), or use one of the various online Regex evaluation sites.
"^[A-Z0-9\-]{6}$"
This conflicts with what you are saying about "expecting 3 characters". This Regex will expect 6, and only 6 characters ranging from A-Z, 0-9, and-or a "-". The text message that is added to the errors collection may still say "3 characters" but that is a misleading message that needs to be updated. Whatever changes you do to the regular expression, you should also update the message behind language.text003, wherever that is coming from. (Resource file, database, etc.)
If the updated text box can accept any number of characters, but still needs to be A-Z, 0-9, and "-" then:
"^[A-Z0-9\-]*"
If you want to impose a maximum of 20 characters for example:
"^[A-Z0-9\-]{0,20}$"
If you want a minimum of 6 and maximum of 20:
"^[A-Z0-9\-]{6,20}$"
If you just want to accept any string and remove the character restrictions all-together, then delete that whole if block.
Related
I have this code in front but I can't build a linked list with more than one element. I see that in the methode "einsetzenNach" the code block in the if statement will never executed. The reason is that the cursor will never get != 0
The code original was in Java.
I am thankful for any tips.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace EinfachVerketteteListe
{
class Program
{
static void Main(string[] args)
{
Liste myList = new Liste();
myList.einsetzenVor(1, "Nr01");
myList.einsetzenVor(2, "Nr02");
myList.einsetzenNach(2, "Nr02");
myList.einsetzenNach(3, "Nr03");
myList.inhalt(3);
myList.laenge();
myList.ToString();
}
}
Here is the Cell class
class Zelle
{
// Contents
public Object inhalt;
// Next cell
public Zelle next;
public Zelle(Object el)
{
inhalt = el;
}
public Zelle(Object el, Zelle z)
{
inhalt = el;
next = z;
}
public Zelle(Zelle z)
{
next = z;
}
}
Our custom list class
public class Liste
{
// Start element
private Zelle anfang;
// Current Element
private Zelle cursor;
/// <summary>
/// There are no more items in the list, start is null
/// </summary>
/// <returns>start == null</returns>
public Boolean IstLeer()
{
return anfang == null;
}
/// <summary>
/// Length of the list
/// </summary>
/// <returns>l = listlenght</returns>
public int laenge()
{
Zelle cur = anfang;
int l = 0;
while (cur != null)
{
l++;
cur = cur.next;
}
return l;
}
/// <summary>
/// Check of the declared position is valid
/// </summary>
/// <param name="p">Position</param>
/// <returns>true/false</returns>
public Boolean istGueltigePosition(int p)
{
return (p >= 1) && (p <= laenge() );
}
/// <summary>
///
/// </summary>
/// <param name="p">Set cursor on a specific position</param>
public void setzeCursor(int p)
{
cursor = null;
if (istGueltigePosition(p))
{
Zelle cur = anfang;
// cur.next is null. The reason is that there is only one element in the list
// How can I fix this block. However I assume the code will work.
// Maybe I handle something not in the correct order.
for (int i = 0; i < p; i++)
{ cur = cur.next; }
cursor = cur;
}
}
Maybe the Methode initCursor() is the answer to my understanding problem.
However I have no idea in which way I can use this methode to print out the first element.
/// <summary>
/// Initial Position Cursor
/// </summary>
public void initCursor()
{
cursor = anfang;
}
/// <summary>
/// Search for specific object and return it's index
/// </summary>
/// <param name="e">Zu findende Daten</param>
/// <returns>p = Index</returns>
public int suche(Object e)
{
cursor = null;
int p = 0, l = 0;
Zelle z = anfang;
while (z != null)
{
l++;
if ( z.inhalt == e )
{
p = l;
cursor = z;
break;
}
z = z.next;
}
return p;
}
/// <summary>
/// Insert cell after element p
/// </summary>
/// <param name="p">Position</param>
/// <param name="e">Daten</param>
public void einsetzenNach(int p, Object e)
{
setzeCursor(p);
This if statment will never get !=0
if (cursor != null)
{
Zelle z = new Zelle(e, cursor.next);
cursor.next = z;
}
}
/// <summary>
/// Insert cell after element p
/// </summary>
/// <param name="p">Position</param>
/// <param name="e">Daten</param>
public void einsetzenVor(int p, Object e)
{
if (p > 1) einsetzenNach(p-1,e);
else
{
// Insert at the beginning
Zelle z = new Zelle(e, anfang);
anfang = z;
}
}
public void loesche(int p)
{
if (istGueltigePosition(p))
{
if (p == 1) // Lösche 1. Object
anfang = anfang.next;
else
{
setzeCursor(p - 1);
cursor.next = cursor.next.next;
}
}
}
/// <summary>
/// Show the content
/// </summary>
/// <param name="p">position</param>
/// <returns></returns>
public Object inhalt(int p)
{
setzeCursor(p);
if (cursor == null) return null;
return cursor.inhalt;
}
/// <summary>
/// next cell/data
/// </summary>
/// <returns>Daten</returns>
public Object naechstes()
{
if (cursor == null) return null;
Object e = cursor.inhalt;
cursor = cursor.next;
return e;
}
}
}
Let's assume you added the first element successfully to the list and now you want to add the second element.
After checking for a valid position you set your current cell to start (Zelle cur = anfang;). After that you want to get to the position where you want to insert your object. But since it is your first element there are no following elements. So cur will always be null after the loop.
Since your list has not a zero-based index you should start your loop with the first index of your list. Try the following loop:
for (int i = 1; i < p; i++)
{
if (cur.next == null)
{
break;
}
cur = cur.next;
}
cursor = cur;
I have an UltraGrid with checkboxes columns.
There are initialized from a web method in Java which is calling the DB for the data. Anyway, when I run the application some checkboxes are already filled and I can check or uncheck.
I would like to retrieve the columns which have been updated. Currently, I did something which allows me to retrieve the status of all the checkboxes and not only the ones I've modified.
Here's the code, the method GetStatusForRow retrieve the status of the checkboxes and GetStatusCheckboxes call the previous method to get the status of all the checkboxes.
public partial class FrmCVault : Form
{
#region Properties
/// <summary>
/// Base filter lists
/// </summary>
//TODO: Change to a CVaultConfiguration Class
public List<BASEFILTER> lBaseFilters { get; private set; }
public List<SITE> lSites { get; private set; }
public List<CONFIGURE> lConfigures{ get; private set; }
#endregion
#region Constructors
/// <summary>
/// Constructor
/// </summary>
public FrmCVault()
{
InitializeComponent();
this.lBaseFilters = null;
this.lSites = null;
this.lConfigures = null;
}
#endregion
#region Private methods
#region Compare byte[]
/// <summary>
/// Compare two byte[]
/// </summary>
/// <param name="b1"></param>
/// <param name="b2"></param>
/// <returns></returns>
private bool Compare(byte[] b1, byte[] b2)
{
// return Encoding.ASCII.GetString(b1) == Encoding.ASCII.GetString(b2);
return b1.SequenceEqual(b2);
}
#endregion
#region Fill the table with Basefilter data
/// <summary>
/// Fill the table with Basefilter data
/// </summary>
private void retrieveData()
{
EVPTProviderBase provider = DataRepository.EVPTProvider;
ObjectDataSet ds = provider.GetBaseFilter();
if (ds != null)
{
this.lBaseFilters = ds.arBASEFILTER.ToList();
this.lSites = ds.arSITE.ToList();
this.lConfigures = ds.arCONFIGURE.ToList();
}
}
#endregion
#region Load Base filter data from DB
/// <summary>
/// Load data from the database
/// </summary>
private void LoadDataSource()
{
CVaultDataSource.Rows.Clear();
if (this.lBaseFilters != null)
{
var filters = from filterBase in this.lBaseFilters
orderby filterBase.EVPTCODE
select new { Id = filterBase.ID, cvault = filterBase.CVAULTCODE, evpt = filterBase.EVPTCODE, desc = filterBase.EVPTDESIGNATION, duration = filterBase.DURATION, time = filterBase.ETDTIME };
var sitesDB = from sites in this.lSites
orderby sites.KEY
select new { SiteKey = sites.KEY, SiteId = sites.ID };
var configs = from config in this.lConfigures
select new { site = config.SITE_ID, baseF = config.BASEFILTER_ID };
object[][] table = new object[filters.Count()][];
int i = 0;
foreach (var item in filters)
{
int j = 0;
table[i] = new object[5 + sitesDB.Count()];
table[i][j++] = item.cvault;
table[i][j++] = item.evpt;
table[i][j++] = item.desc;
table[i][j++] = item.duration;
table[i][j++] = item.time;
foreach (var site in sitesDB)
{
table[i][j] = false;
foreach (var conf in configs)
{
if (Compare(site.SiteId, conf.site) && Compare(conf.baseF, item.Id))
{
table[i][j] = true;
break;
}
}
j++;
}
i++;
}
foreach (var item in table)
{
CVaultDataSource.Rows.Add(item);
}
}
}
#endregion
#region Add column sites
/// <summary>
/// Add columns in table according to the sites stored in DB
/// </summary>
/// <remarks>The action is used to create site column</remarks>
private void AddColumnSites()
{
const string siteCol = "SITE_COL";
var addNewSite = new Action<string>(site =>
{
if (siteCol != "OTHER")
{
var ultraGridBand = this.CVaultGrid.DisplayLayout.Bands[0];
var gridDataColumn = new UltraDataColumn(site);
gridDataColumn.DataType = typeof(bool);
gridDataColumn.Tag = siteCol;
gridDataColumn.DataType = typeof(bool);
gridDataColumn.DefaultValue = false;
this.CVaultDataSource.Band.Columns.AddRange(new object[] {
gridDataColumn
});
}
});
for (int i = this.CVaultDataSource.Band.Columns.Count-1; i >= 0 ; i--)
{
if (this.CVaultDataSource.Band.Columns[i].Tag == siteCol)
{
this.CVaultDataSource.Band.Columns.RemoveAt(i);
}
}
var sitesDB = from sites in this.lSites
orderby sites.KEY
select sites.KEY ;
foreach (var item in sitesDB)
{
addNewSite(item);
}
}
#endregion
#region Retrieve status of checkboxes
/// <summary>
/// Retrieve the checkboxes's status of the last row selected
/// </summary>
/// <param name="b"></param>
/// <param name="row"></param>
/// <returns></returns>
private Dictionary<string, bool> GetStatusForRow(UltraDataBand b, UltraDataRow row)
{
Dictionary<string, bool> statusChecked = new Dictionary<string, bool>();
foreach (UltraDataColumn col in b.Columns.Cast<UltraDataColumn>()
.Where(x => x.Tag != null &&
x.Tag.ToString() == "SITE_COL"))
{
statusChecked.Add(col.Key, Convert.ToBoolean(row.GetCellValue(col)));
}
return statusChecked;
}
#endregion
#region Retrieve status of hours columns
private Dictionary<string, string> GetStatusHoursForRow(UltraDataBand b, UltraGridRow row)
{
Dictionary<string, string> statusChecked = new Dictionary<string, string>();
foreach (UltraDataColumn col in b.Columns.Cast<UltraDataColumn>()
.Where(x => x.Tag != null &&
x.Tag.ToString() == "SITE_COL"))
{
//statusChecked.Add(,);
}
return statusChecked;
}
#endregion
#endregion
#region Form Events
/// <summary>
/// Form loading event
/// </summary>
/// <param name="sender">Form</param>
/// <param name="e">Arguments (empty)</param>
private void FrmCVault_Load(object sender, EventArgs e)
{
this.retrieveData();
this.AddColumnSites();
this.LoadDataSource();
CVaultGrid.DataBind();
}
private void ultraButton2_Click(object sender, EventArgs e)
{
CVaultGrid.ActiveRow.Update();
CVaultGrid.DisplayLayout.Bands[0].AddNew();
}
private void FrmCVault_Shown(object sender, EventArgs e)
{
CVaultGrid.DisplayLayout.Bands[0].AddNew();
}
private void vl_ItemNotInList(object sender, ValidationErrorEventArgs e)
{
var ultrCombo = sender as UltraComboEditor;
e.RetainFocus = true;
if (e.LastValidValue != null)
ultrCombo.Value = e.LastValidValue;
else if (ultrCombo.Items.Count>0)
ultrCombo.SelectedItem = ultrCombo.Items[0];
}
private void ultraGrid1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Enter)
{
CVaultGrid.UpdateData();
}
}
private void Cancel_Click(object sender, EventArgs e)
{
this.Close();
}
private void SAVE_Click(object sender, System.EventArgs e)
{
this.GetStatusCheckboxes();
this.GetStatusHours();
}
/// <summary>
/// Get the status of checkboxes which have been changed (check or uncheck)
/// </summary>
private void GetStatusCheckboxes()
{
var statusChecked = new Dictionary<string, Dictionary<string, bool>>();
foreach (UltraDataRow row in CVaultDataSource.Rows)
{
statusChecked.Add(row.GetCellValue(0).ToString(), GetStatusForRow(CVaultDataSource.Band, row));
}
foreach (KeyValuePair<string, Dictionary<string, bool>> kvp in statusChecked)
{
foreach (var sr in kvp.Value)
{
Console.WriteLine(string.Format("[{0}] Status site: {1} is {2}", kvp.Key, sr.Key, sr.Value));
}
}
Console.WriteLine("\r\n");
}
/// <summary>
/// Get back the hour which have been updated
/// From the column DURATION or ETD
/// </summary>
private void GetStatusHours()
{
//GetStatusHoursForRow(CVaultDataSource.Band, CVaultGrid.ActiveRow);
//Dictionary<string, bool> statusChecked = GetStatusForRow(CVaultDataSource.Band, CVaultGrid.ActiveRow);
//foreach (KeyValuePair<string, bool> kvp in statusChecked)
// Console.WriteLine("Status site:" + kvp.Key + " is " + kvp.Value.ToString());
//Console.WriteLine("\r\n");
}
#endregion
private void CVaultGrid_InitializeLayout(object sender, InitializeLayoutEventArgs e)
{
}
}
Here's a screen to see the windows:
Better than check the status of the entire row to see if CheckBox of a column is SET or not is intercept ITS EVENT like:
Public Sub dataGridView1_CellValueChanged(ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs) _
Handles dataGridView1.CellValueChanged
If dataGridView1.Columns(e.ColumnIndex).Name = "MyCheckBox" Then
Dim checkCell As DataGridViewCheckBoxCell = _
CType(dataGridView1.Rows(e.RowIndex).Cells("MyCheckBox"), _
DataGridViewCheckBoxCell)
Dim IsSet as boolean = checkCell.Value
dataGridView1.Invalidate()
End If
End Sub
My combobox returns a set of values from s stored procedure as this
private void BindCombo()
{
DataCombo.FillCombo(ComboDS(2313001), cmbClass, 0);
DataCombo.FillCombo(DDCombo(5007), cmbGroup, 0);
}
I managed to give a rudimentary auto complete suggestion as IsTextSearchenabled but cannot get a auto suggestion box that i would like.
I have seen loads of examples of autocomplete/suggestive textboxes but none of them seem to suit me.
this code apparently suits me.
but how would i use the auto suggest here
using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace DotNetZen.AutoFilteredComboBox
{
public class AutoFilteredComboBox : ComboBox
{
private int silenceEvents = 0;
/// <summary>
/// Creates a new instance of <see cref="AutoFilteredComboBox" />.
/// </summary>
public AutoFilteredComboBox()
{
DependencyPropertyDescriptor textProperty = DependencyPropertyDescriptor.FromProperty(
ComboBox.TextProperty, typeof(AutoFilteredComboBox));
textProperty.AddValueChanged(this, this.OnTextChanged);
this.RegisterIsCaseSensitiveChangeNotification();
}
#region IsCaseSensitive Dependency Property
/// <summary>
/// The <see cref="DependencyProperty"/> object of the <see cref="IsCaseSensitive" /> dependency property.
/// </summary>
public static readonly DependencyProperty IsCaseSensitiveProperty =
DependencyProperty.Register("IsCaseSensitive", typeof(bool), typeof(AutoFilteredComboBox), new UIPropertyMetadata(false));
/// <summary>
/// Gets or sets the way the combo box treats the case sensitivity of typed text.
/// </summary>
/// <value>The way the combo box treats the case sensitivity of typed text.</value>
[System.ComponentModel.Description("The way the combo box treats the case sensitivity of typed text.")]
[System.ComponentModel.Category("AutoFiltered ComboBox")]
[System.ComponentModel.DefaultValue(true)]
public bool IsCaseSensitive
{
[System.Diagnostics.DebuggerStepThrough]
get
{
return (bool)this.GetValue(IsCaseSensitiveProperty);
}
[System.Diagnostics.DebuggerStepThrough]
set
{
this.SetValue(IsCaseSensitiveProperty, value);
}
}
protected virtual void OnIsCaseSensitiveChanged(object sender, EventArgs e)
{
if (this.IsCaseSensitive)
this.IsTextSearchEnabled = false;
this.RefreshFilter();
}
private void RegisterIsCaseSensitiveChangeNotification()
{
System.ComponentModel.DependencyPropertyDescriptor.FromProperty(IsCaseSensitiveProperty, typeof(AutoFilteredComboBox)).AddValueChanged(
this, this.OnIsCaseSensitiveChanged);
}
#endregion
#region DropDownOnFocus Dependency Property
/// <summary>
/// The <see cref="DependencyProperty"/> object of the <see cref="DropDownOnFocus" /> dependency property.
/// </summary>
public static readonly DependencyProperty DropDownOnFocusProperty =
DependencyProperty.Register("DropDownOnFocus", typeof(bool), typeof(AutoFilteredComboBox), new UIPropertyMetadata(true));
/// <summary>
/// Gets or sets the way the combo box behaves when it receives focus.
/// </summary>
/// <value>The way the combo box behaves when it receives focus.</value>
[System.ComponentModel.Description("The way the combo box behaves when it receives focus.")]
[System.ComponentModel.Category("AutoFiltered ComboBox")]
[System.ComponentModel.DefaultValue(true)]
public bool DropDownOnFocus
{
[System.Diagnostics.DebuggerStepThrough]
get
{
return (bool)this.GetValue(DropDownOnFocusProperty);
}
[System.Diagnostics.DebuggerStepThrough]
set
{
this.SetValue(DropDownOnFocusProperty, value);
}
}
#endregion
#region | Handle selection |
/// <summary>
/// Called when <see cref="ComboBox.ApplyTemplate()"/> is called.
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.EditableTextBox.SelectionChanged += this.EditableTextBox_SelectionChanged;
}
/// <summary>
/// Gets the text box in charge of the editable portion of the combo box.
/// </summary>
protected TextBox EditableTextBox
{
get
{
return ((TextBox)base.GetTemplateChild("PART_EditableTextBox"));
}
}
private int start = 0, length = 0;
private void EditableTextBox_SelectionChanged(object sender, RoutedEventArgs e)
{
if (this.silenceEvents == 0)
{
this.start = ((TextBox)(e.OriginalSource)).SelectionStart;
this.length = ((TextBox)(e.OriginalSource)).SelectionLength;
this.RefreshFilter();
}
}
#endregion
#region | Handle focus |
/// <summary>
/// Invoked whenever an unhandled <see cref="UIElement.GotFocus" /> event
/// reaches this element in its route.
/// </summary>
/// <param name="e">The <see cref="RoutedEventArgs" /> that contains the event data.</param>
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
if (this.ItemsSource != null && this.DropDownOnFocus)
{
this.IsDropDownOpen = true;
}
}
#endregion
#region | Handle filtering |
private void RefreshFilter()
{
if (this.ItemsSource != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(this.ItemsSource);
view.Refresh();
this.IsDropDownOpen = true;
}
}
private bool FilterPredicate(object value)
{
// We don't like nulls.
if (value == null)
return false;
// If there is no text, there's no reason to filter.
if (this.Text.Length == 0)
return true;
string prefix = this.Text;
// If the end of the text is selected, do not mind it.
if (this.length > 0 && this.start + this.length == this.Text.Length)
{
prefix = prefix.Substring(0, this.start);
}
return value.ToString()
.StartsWith(prefix, !this.IsCaseSensitive, CultureInfo.CurrentCulture);
}
#endregion
/// <summary>
/// Called when the source of an item in a selector changes.
/// </summary>
/// <param name="oldValue">Old value of the source.</param>
/// <param name="newValue">New value of the source.</param>
protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue)
{
if (newValue != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(newValue);
view.Filter += this.FilterPredicate;
}
if (oldValue != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(oldValue);
view.Filter -= this.FilterPredicate;
}
base.OnItemsSourceChanged(oldValue, newValue);
}
private void OnTextChanged(object sender, EventArgs e)
{
if (!this.IsTextSearchEnabled && this.silenceEvents == 0)
{
this.RefreshFilter();
// Manually simulate the automatic selection that would have been
// available if the IsTextSearchEnabled dependency property was set.
if (this.Text.Length > 0)
{
foreach (object item in CollectionViewSource.GetDefaultView(this.ItemsSource))
{
int text = item.ToString().Length, prefix = this.Text.Length;
this.SelectedItem = item;
this.silenceEvents++;
this.EditableTextBox.Text = item.ToString();
this.EditableTextBox.Select(prefix, text - prefix);
this.silenceEvents--;
break;
}
}
}
}
}
}
Also found the AutoFilteredComboBox to be very simple to work with. Though I have made some changes:
Removed use of DependencyPropertyDescriptor to avoid memory leak of combobox-objects
Introduced FilterItem-event and FilterList-event to allow one to customize the filtering
Changed default filtering from starts-with-string to contains-string
Removed support of having IsTextSearchEnabled enabled
Shows dropdown as soon one changes the search string, so search result is displayed
Example of how it is used:
<Controls:AutoFilteredComboBox ItemsSource="{Binding ViewModel.AvailableItems}"
SelectedValue="{Binding ViewModel.SelectedItem, Mode=TwoWay}"
IsEditable="True" IsTextSearchEnabled="False"/>
Improved version of AutoFilteredComboBox:
public class AutoFilteredComboBox : ComboBox
{
bool _ignoreTextChanged;
string _currentText;
/// <summary>
/// Creates a new instance of <see cref="AutoFilteredComboBox" />.
/// </summary>
public AutoFilteredComboBox()
{
if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) return;
}
public event Func<object, string, bool> FilterItem;
public event Action<string> FilterList;
#region IsCaseSensitive Dependency Property
/// <summary>
/// The <see cref="DependencyProperty"/> object of the <see cref="IsCaseSensitive" /> dependency property.
/// </summary>
public static readonly DependencyProperty IsCaseSensitiveProperty =
DependencyProperty.Register("IsCaseSensitive", typeof(bool), typeof(AutoFilteredComboBox), new UIPropertyMetadata(false));
/// <summary>
/// Gets or sets the way the combo box treats the case sensitivity of typed text.
/// </summary>
/// <value>The way the combo box treats the case sensitivity of typed text.</value>
[Description("The way the combo box treats the case sensitivity of typed text.")]
[Category("AutoFiltered ComboBox")]
[DefaultValue(true)]
public bool IsCaseSensitive
{
[System.Diagnostics.DebuggerStepThrough]
get
{
return (bool)this.GetValue(IsCaseSensitiveProperty);
}
[System.Diagnostics.DebuggerStepThrough]
set
{
this.SetValue(IsCaseSensitiveProperty, value);
}
}
#endregion
#region DropDownOnFocus Dependency Property
/// <summary>
/// The <see cref="DependencyProperty"/> object of the <see cref="DropDownOnFocus" /> dependency property.
/// </summary>
public static readonly DependencyProperty DropDownOnFocusProperty =
DependencyProperty.Register("DropDownOnFocus", typeof(bool), typeof(AutoFilteredComboBox), new UIPropertyMetadata(false));
/// <summary>
/// Gets or sets the way the combo box behaves when it receives focus.
/// </summary>
/// <value>The way the combo box behaves when it receives focus.</value>
[Description("The way the combo box behaves when it receives focus.")]
[Category("AutoFiltered ComboBox")]
[DefaultValue(false)]
public bool DropDownOnFocus
{
[System.Diagnostics.DebuggerStepThrough]
get
{
return (bool)this.GetValue(DropDownOnFocusProperty);
}
[System.Diagnostics.DebuggerStepThrough]
set
{
this.SetValue(DropDownOnFocusProperty, value);
}
}
#endregion
#region | Handle focus |
/// <summary>
/// Invoked whenever an unhandled <see cref="UIElement.GotFocus" /> event
/// reaches this element in its route.
/// </summary>
/// <param name="e">The <see cref="RoutedEventArgs" /> that contains the event data.</param>
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
if (this.ItemsSource != null && this.DropDownOnFocus)
{
this.IsDropDownOpen = true;
}
}
#endregion
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(OnTextChanged));
KeyUp += AutoFilteredComboBox_KeyUp;
this.IsTextSearchEnabled = false;
}
void AutoFilteredComboBox_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Down)
{
if (this.IsDropDownOpen == true)
{
// Ensure that focus is given to the dropdown list
if (Keyboard.FocusedElement is TextBox)
{
Keyboard.Focus(this);
if (this.Items.Count > 0)
{
if (this.SelectedIndex == -1 || this.SelectedIndex==0)
this.SelectedIndex = 0;
}
}
}
}
if (Keyboard.FocusedElement is TextBox)
{
if (e.OriginalSource is TextBox)
{
// Avoid the automatic selection of the first letter (As next letter will cause overwrite)
TextBox textBox = e.OriginalSource as TextBox;
if (textBox.Text.Length == 1 && textBox.SelectionLength == 1)
{
textBox.SelectionLength = 0;
textBox.SelectionStart = 1;
}
}
}
}
#region | Handle filtering |
private void RefreshFilter()
{
if (this.ItemsSource != null)
{
Action<string> filterList = FilterList;
if (filterList != null)
{
filterList(_currentText);
}
else
{
ICollectionView view = CollectionViewSource.GetDefaultView(this.ItemsSource);
view.Refresh();
}
this.SelectedIndex = -1; // Prepare so arrow down selects first
this.IsDropDownOpen = true;
}
}
private bool FilterPredicate(object value)
{
// We don't like nulls.
if (value == null)
return false;
// If there is no text, there's no reason to filter.
if (string.IsNullOrEmpty(_currentText))
return true;
Func<object, string, bool> filterItem = FilterItem;
if (filterItem != null)
return filterItem(value, _currentText);
if (IsCaseSensitive)
return value.ToString().Contains(_currentText);
else
return value.ToString().ToUpper().Contains(_currentText.ToUpper());
}
#endregion
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
try
{
_ignoreTextChanged = true; // Ignore the following TextChanged
base.OnSelectionChanged(e);
}
finally
{
_ignoreTextChanged = false;
}
}
/// <summary>
/// Called when the source of an item in a selector changes.
/// </summary>
/// <param name="oldValue">Old value of the source.</param>
/// <param name="newValue">New value of the source.</param>
protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
{
if (newValue != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(newValue);
if (FilterList == null)
view.Filter += this.FilterPredicate;
}
if (oldValue != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(oldValue);
view.Filter -= this.FilterPredicate;
}
base.OnItemsSourceChanged(oldValue, newValue);
}
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
if (_ignoreTextChanged)
return;
_currentText = Text;
if (!this.IsTextSearchEnabled)
{
this.RefreshFilter();
}
}
I have found a super simple workaround to my problem.
i created a preview text input event of the combobox.
then i just wrote
Combobox.IsDropDownOpen = true
may not the most elegant but works in my case
I'm in need to load an bunch of bitmaps in my application. The problem is that the loading make the form very slow. My actual class is as follows:
public class ImagensDisponiveis
{
/// <summary>
/// List of ImagemSygic struct
/// </summary>
private List<ImagemSygic> _poolImagens;
/// <summary>
/// index of next avaiable image
/// </summary>
private int indiceProximoDisponivel;
/// <summary>
/// Path to image folder
/// </summary>
private string caminhoPasta;
/// <summary>
/// Number of found images that conforms to patterm
/// </summary>
private int MAXCOUNT;
public ImagensDisponiveis(string caminhoPastaRecursos)
{
indiceProximoDisponivel = 0;
caminhoPasta = caminhoPastaRecursos;
PreencherPool(out _poolImagens, caminhoPasta);
MAXCOUNT = _poolImagens.Count;
}
/// <summary>
/// Preenche a lista de imagens com uma estrutura que contém a imagem e o caminho dessa imagem para o Sygic
/// </summary>
/// <param name="_poolImagens">The _pool imagens.</param>
/// <param name="filepath">The filepath.</param>
private void PreencherPool(out List<ImagemSygic> _poolImagens, string filepath)
{
DateTime momentoInicio = DateTime.Now;
_poolImagens = new List<ImagemSygic>();
string[] imagens = Directory.GetFiles(filepath);
#if DEBUG
//int counter = 0;
//int numFiles = imagens.Length;
#endif
foreach (string caminhoImagem in imagens)
{
try
{
string filename = Path.GetFileName(caminhoImagem);
//original image to show on .net [POI]anything.bmp
//image that sygic tries to use on drive ?[POI]anything.bmp, where ? is an number between 1 to 6
bool valido = filename.StartsWith("[POI]", StringComparison.InvariantCulture);
//Log.writeToLog(caminhoImagem + " " + valido.ToString());
if (valido)
{
var streamImagem = File.Open(caminhoImagem, FileMode.Open, FileAccess.Read);
Bitmap temImagem = new Bitmap(streamImagem);
ImagemSygic tempImgSygic = new ImagemSygic();
tempImgSygic.CaminhoImagemSygic = caminhoImagem;
tempImgSygic.ImagemWindows = temImagem;
tempImgSygic.SygicImageID = -1;
_poolImagens.Add(tempImgSygic);
#if DEBUG
//counter++;
#endif
}
}
catch (ArgumentException aec)
{
Log.writeToLog("[EXCEPCAO ImagensDisp]: ArgumentException - " + aec.Message);
}
catch (UnauthorizedAccessException uae)
{
Log.writeToLog("[EXCEPCAO ImagensDisp]: UnauthorizedAccessException - " + uae.Message);
}
catch (Exception exc)
{
Log.writeToLog("[EXCEPCAO ImagensDisp]: Exception - " + exc.Message);
}
}
DateTime tempoFim = DateTime.Now;
TimeSpan duracao = tempoFim.Subtract(momentoInicio);
Log.writeToLog("[Criacao da pool] Demorou " + duracao.TotalSeconds.ToString());
}
/// <summary>
/// OObtains the next avaianle ImagemSygic if there is an avaiable
/// </summary>
/// <returns>ImagemSygic if possible, else null</returns>
public ImagemSygic ObterProximoDisponivel()
{
if (indiceProximoDisponivel > MAXCOUNT)
return null;
else
{
ImagemSygic imagemRetornar = _poolImagens[indiceProximoDisponivel];
indiceProximoDisponivel++;
return imagemRetornar;
}
}
public void ResetCounter()
{
indiceProximoDisponivel = 0;
}
}
/// <summary>
/// Class that contains the Bitmap preview and the original path to that image
/// </summary>
public class ImagemSygic
{
private volatile int _imageID;
/// <summary>
/// Gets or sets the imagem windows.
/// </summary>
/// <value>The imagem windows.</value>
public Bitmap ImagemWindows { get; set; }
/// <summary>
/// Gets or sets the caminho imagem sygic.
/// </summary>
/// <value>The caminho imagem sygic.</value>
public string CaminhoImagemSygic { get; set; }
/// <summary>
/// Gets or sets the sygic image ID.
/// </summary>
/// <value>The sygic image ID.</value>
public int SygicImageID
{
get
{
return this._imageID;
}
set
{
this._imageID = value;
}
}
}
/// <summary>
///
/// </summary>
public class POISygic
{
private volatile int _latitude;
private volatile int _longitude;
/// <summary>
/// Gets or sets the imagem.
/// </summary>
/// <value>The imagem.</value>
public ImagemSygic Imagem { get; set; }
/// <summary>
/// Gets or sets the latitude.
/// </summary>
/// <value>The latitude.</value>
public int Latitude { get { return this._latitude; } set { this._latitude = value; } }
/// <summary>
/// Gets or sets the longitude.
/// </summary>
/// <value>The longitude.</value>
public int Longitude { get { return this._longitude; } set { this._longitude = value; } }
/// <summary>
/// Gets or sets the descricao.
/// </summary>
/// <value>The descricao.</value>
public string Descricao { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is displayed now.
/// </summary>
/// <value>
/// <c>true</c> if this instance is displayed now; otherwise, <c>false</c>.
/// </value>
public bool isDisplayedNow { get; set; }
/// <summary>
/// Gets or sets the elem ID.
/// </summary>
/// <value>The elem ID.</value>
public int elemID { get; set; }
}
The objective of this class is to read an serie of bitmaps that have the [POI] prefix to allow .net to display an legend in an form control to the poi image appearing in an Sygic Drive window.
The question is how i can optimize this code to load the images faster. At the moment it loads 26 315k bitmaps images in 10s. But probably in the final solution we could have as many as +260 images, so that is the reason of the need of optimization.
The biggest potential improvement I see is that PreencherPool loads all images in a folder. Are you showing all images at once? If not, you could change that to lazy-load the images on demand, or at least load them in a background thread so the caller doesn't block while they all get loaded.
I'd also suggest that 300k seems a bit large for a "thumbnail" (which the code suggests they are). Are you sizing it to what you actually need for displ15?
I have seen threads on many sites regarding extending the gridview control so obviously this will be a duplicate. But I haven't found any that truly extend the control to the extent that you could have custom sorting (with header images), filtering by putting drop downs or textboxes in header columns (on a column by column basis) and custom paging (one that doesn't return all records but just returns the ones requested for the given page).
Are there any good tutorials that show the inner-workings of the gridview and how to override the proper functions? I've seen several snippets here and there but none seem to really work and explain things well.
Any links would be appreciated. Thanks!
I've extended the GridView control myself to allow sorting with images, custom paging (so you can select how many records per page from a drop-down) and a few other things. However, you won't be able to do custom paging that just returns the records for the requested page, as that is something your datasource needs to handle and not the GridView.
All I can really do is give you some code and hope it helps. It's pretty old code (pre C#3.0) but may be of some use:
First of all here's the custom GridView control that extends the standard GridView:
using System;
using System.Collections;
using System.Drawing;
using System.Web.UI.WebControls;
using Diplo.WebControls.DataControls.PagerTemplates;
using Image=System.Web.UI.WebControls.Image;
namespace Diplo.WebControls.DataControls
{
/// <summary>
/// Extended <see cref="GridView"/> with some additional cool properties
/// </summary>
public class DiploGridView : GridView
{
#region Properties
/// <summary>
/// Gets or sets a value indicating whether a sort graphic is shown in column headings
/// </summary>
/// <value><c>true</c> if sort graphic is displayed; otherwise, <c>false</c>.</value>
public bool EnableSortGraphic
{
get
{
object o = ViewState["EnableSortGraphic"];
if (o != null)
{
return (bool)o;
}
return true;
}
set
{
ViewState["EnableSortGraphic"] = value;
}
}
/// <summary>
/// Gets or sets the sort ascending image when <see cref="EnableSortGraphic"/> is <c>true</c>
/// </summary>
public string SortAscendingImage
{
get
{
object o = ViewState["SortAscendingImage"];
if (o != null)
{
return (string)o;
}
return Page.ClientScript.GetWebResourceUrl(GetType(), SharedWebResources.ArrowUpImage);
}
set
{
ViewState["SortAscendingImage"] = value;
}
}
/// <summary>
/// Gets or sets the sort descending image <see cref="EnableSortGraphic"/> is <c>true</c>
/// </summary>
public string SortDescendingImage
{
get
{
object o = ViewState["SortDescendingImage"];
if (o != null)
{
return (string)o;
}
return Page.ClientScript.GetWebResourceUrl(GetType(), SharedWebResources.ArrowDownImage);
}
set
{
ViewState["SortDescendingImage"] = value;
}
}
/// <summary>
/// Gets or sets the custom pager settings mode.
/// </summary>
public CustomPagerMode CustomPagerSettingsMode
{
get
{
object o = ViewState["CustomPagerSettingsMode"];
if (o != null)
{
return (CustomPagerMode)o;
}
return CustomPagerMode.None;
}
set
{
ViewState["CustomPagerSettingsMode"] = value;
}
}
/// <summary>
/// Gets or sets a value indicating whether the columns in the grid can be re-sized in the UI
/// </summary>
/// <value><c>true</c> if column resizing is allowed; otherwise, <c>false</c>.</value>
public bool AllowColumnResizing
{
get
{
object o = ViewState["AllowColumnResizing"];
if (o != null)
{
return (bool)o;
}
return false;
}
set
{
ViewState["AllowColumnResizing"] = value;
}
}
/// <summary>
/// Gets or sets the highlight colour for the row
/// </summary>
public Color RowStyleHighlightColour
{
get
{
object o = ViewState["RowStyleHighlightColour"];
if (o != null)
{
return (Color)o;
}
return Color.Empty;
}
set
{
ViewState["RowStyleHighlightColour"] = value;
}
}
#endregion Properties
#region Enums
/// <summary>
/// Represents additional custom paging modes
/// </summary>
public enum CustomPagerMode
{
/// <summary>
/// No custom paging mode
/// </summary>
None,
/// <summary>
/// Shows the rows drop-down list <i>and</i> the previous and next buttons
/// </summary>
RowsPagePreviousNext,
/// <summary>
/// Only shows the previous and next buttons
/// </summary>
PagePreviousNext
}
#endregion
#region Overridden Events
/// <summary>
/// Initializes the pager row displayed when the paging feature is enabled.
/// </summary>
/// <param name="row">A <see cref="T:System.Web.UI.WebControls.GridViewRow"></see> that represents the pager row to initialize.</param>
/// <param name="columnSpan">The number of columns the pager row should span.</param>
/// <param name="pagedDataSource">A <see cref="T:System.Web.UI.WebControls.PagedDataSource"></see> that represents the data source.</param>
protected override void InitializePager(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource)
{
switch (CustomPagerSettingsMode)
{
case CustomPagerMode.RowsPagePreviousNext:
PagerTemplate = new RowsPagePreviousNext(pagedDataSource, this);
break;
case CustomPagerMode.PagePreviousNext:
PagerTemplate = new PagePreviousNext(pagedDataSource, this);
break;
case CustomPagerMode.None:
break;
default:
break;
}
base.InitializePager(row, columnSpan, pagedDataSource);
}
/// <summary>
/// Raises the <see cref="E:System.Web.UI.Control.PreRender"></see> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
protected override void OnPreRender(EventArgs e)
{
if (AllowColumnResizing && Visible)
{
string vars = String.Format("var _DiploGridviewId = '{0}';\n", ClientID);
if (!Page.ClientScript.IsClientScriptBlockRegistered("Diplo_GridViewVars"))
{
Page.ClientScript.RegisterClientScriptBlock(GetType(), "Diplo_GridViewVars", vars, true);
}
Page.ClientScript.RegisterClientScriptInclude("Diplo_GridView.js",
Page.ClientScript.GetWebResourceUrl(GetType(), "Diplo.WebControls.SharedWebResources.Diplo_GridView_Resize.js"));
}
base.OnPreRender(e);
}
/// <summary>
/// Raises the <see cref="E:System.Web.UI.WebControls.GridView.RowCreated"></see> event.
/// </summary>
/// <param name="e">A <see cref="T:System.Web.UI.WebControls.GridViewRowEventArgs"></see> that contains event data.</param>
protected override void OnRowCreated(GridViewRowEventArgs e)
{
if (EnableSortGraphic)
{
if (!((e.Row == null)) && e.Row.RowType == DataControlRowType.Header)
{
foreach (TableCell cell in e.Row.Cells)
{
if (cell.HasControls())
{
LinkButton button = ((LinkButton)(cell.Controls[0]));
if (!((button == null)))
{
Image image = new Image();
image.ImageUrl = "images/default.gif";
image.ImageAlign = ImageAlign.Baseline;
if (SortExpression == button.CommandArgument)
{
image.ImageUrl = SortDirection == SortDirection.Ascending ? SortAscendingImage : SortDescendingImage;
Literal space = new Literal();
space.Text = " ";
cell.Controls.Add(space);
cell.Controls.Add(image);
}
}
}
}
}
}
if (RowStyleHighlightColour != Color.Empty)
{
if (e.Row != null)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Attributes.Add("onmouseover", String.Format("this.style.backgroundColor='{0}'", ColorTranslator.ToHtml(RowStyleHighlightColour)));
e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor=''");
}
}
}
base.OnRowCreated(e);
}
/// <summary>
/// Creates the control hierarchy that is used to render a composite data-bound control based on the values that are stored in view state.
/// </summary>
protected override void CreateChildControls()
{
base.CreateChildControls();
CheckShowPager();
}
private void CheckShowPager()
{
if (CustomPagerSettingsMode != CustomPagerMode.None && AllowPaging)
{
if (TopPagerRow != null)
{
TopPagerRow.Visible = true;
}
if (BottomPagerRow != null)
{
BottomPagerRow.Visible = true;
}
}
}
/// <summary>
/// Creates the control hierarchy used to render the <see cref="T:System.Web.UI.WebControls.GridView"></see> control using the specified data source.
/// </summary>
/// <param name="dataSource">An <see cref="T:System.Collections.IEnumerable"></see> that contains the data source for the <see cref="T:System.Web.UI.WebControls.GridView"></see> control.</param>
/// <param name="dataBinding">true to indicate that the child controls are bound to data; otherwise, false.</param>
/// <returns>The number of rows created.</returns>
protected override int CreateChildControls(IEnumerable dataSource, bool dataBinding)
{
int i = base.CreateChildControls(dataSource, dataBinding);
CheckShowPager();
return i;
}
#endregion Overridden Events
}
}
Then there is a custom paging class that is used as a paging template:
using System;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Web.UI;
namespace Diplo.WebControls.DataControls.PagerTemplates
{
/// <summary>
/// Paging template for the <see cref="DiploGridView"/>
/// </summary>
public class RowsPagePreviousNext : ITemplate
{
readonly PagedDataSource _pagedDataSource;
readonly DiploGridView DiploGridView;
/// <summary>
/// Initializes a new instance of the <see cref="RowsPagePreviousNext"/> class.
/// </summary>
/// <param name="pagedDataSource">The <see cref="PagedDataSource"/>.</param>
/// <param name="DiploGrid">A reference to the <see cref="DiploGridView"/>.</param>
public RowsPagePreviousNext(PagedDataSource pagedDataSource, DiploGridView DiploGrid)
{
_pagedDataSource = pagedDataSource;
DiploGridView = DiploGrid;
}
/// <summary>
/// When implemented by a class, defines the <see cref="T:System.Web.UI.Control"></see> object that child controls and templates belong to. These child controls are in turn defined within an inline template.
/// </summary>
/// <param name="container">The <see cref="T:System.Web.UI.Control"></see> object to contain the instances of controls from the inline template.</param>
void ITemplate.InstantiateIn(Control container)
{
Literal space = new Literal();
space.Text = " ";
HtmlGenericControl divLeft = new HtmlGenericControl("div");
divLeft.Style.Add("float", "left");
divLeft.Style.Add(HtmlTextWriterStyle.Width, "25%");
Label lb = new Label();
lb.Text = "Show rows: ";
divLeft.Controls.Add(lb);
DropDownList ddlPageSize = new DropDownList();
ListItem item;
ddlPageSize.AutoPostBack = true;
ddlPageSize.ToolTip = "Select number of rows per page";
int max = (_pagedDataSource.DataSourceCount < 50) ? _pagedDataSource.DataSourceCount : 50;
int i;
const int increment = 5;
bool alreadySelected = false;
for (i = increment; i <= max; i = i + increment)
{
item = new ListItem(i.ToString());
if (i == _pagedDataSource.PageSize)
{
item.Selected = true;
alreadySelected = true;
}
ddlPageSize.Items.Add(item);
}
item = new ListItem("All", _pagedDataSource.DataSourceCount.ToString());
if (_pagedDataSource.DataSourceCount == _pagedDataSource.PageSize && alreadySelected == false)
{
item.Selected = true;
alreadySelected = true;
}
if (_pagedDataSource.DataSourceCount > (i - increment) && alreadySelected == false)
{
item.Selected = true;
}
ddlPageSize.Items.Add(item);
ddlPageSize.SelectedIndexChanged += new EventHandler(ddlPageSize_SelectedIndexChanged);
divLeft.Controls.Add(ddlPageSize);
HtmlGenericControl divRight = new HtmlGenericControl("div");
divRight.Style.Add("float", "right");
divRight.Style.Add(HtmlTextWriterStyle.Width, "75%");
divRight.Style.Add(HtmlTextWriterStyle.TextAlign, "right");
Literal lit = new Literal();
lit.Text = String.Format("Found {0} record{1}. Page ",
_pagedDataSource.DataSourceCount,
(_pagedDataSource.DataSourceCount == 1) ? String.Empty : "s" );
divRight.Controls.Add(lit);
TextBox tbPage = new TextBox();
tbPage.ToolTip = "Enter page number";
tbPage.Columns = 2;
tbPage.MaxLength = 3;
tbPage.Text = (_pagedDataSource.CurrentPageIndex + 1).ToString();
tbPage.CssClass = "pagerTextBox";
tbPage.AutoPostBack = true;
tbPage.TextChanged += new EventHandler(tbPage_TextChanged);
divRight.Controls.Add(tbPage);
if (_pagedDataSource.PageCount < 2)
tbPage.Enabled = false;
lit = new Literal();
lit.Text = " of " + _pagedDataSource.PageCount;
divRight.Controls.Add(lit);
divRight.Controls.Add(space);
Button btn = new Button();
btn.Text = "";
btn.CommandName = "Page";
btn.CommandArgument = "Prev";
btn.SkinID = "none";
btn.Enabled = !_pagedDataSource.IsFirstPage;
btn.CssClass = (btn.Enabled) ? "buttonPreviousPage" : "buttonPreviousPageDisabled";
if (btn.Enabled)
btn.ToolTip = "Previous page";
divRight.Controls.Add(btn);
btn = new Button();
btn.Text = "";
btn.CommandName = "Page";
btn.CommandArgument = "Next";
btn.SkinID = "none";
btn.CssClass = "buttonNext";
btn.Enabled = !_pagedDataSource.IsLastPage;
btn.CssClass = (btn.Enabled) ? "buttonNextPage" : "buttonNextPageDisabled";
if (btn.Enabled)
btn.ToolTip = "Next page";
divRight.Controls.Add(btn);
container.Controls.Add(divLeft);
container.Controls.Add(divRight);
}
/// <summary>
/// Handles the TextChanged event of the tbPage control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
void tbPage_TextChanged(object sender, EventArgs e)
{
TextBox tb = sender as TextBox;
if (tb != null)
{
int page;
if (int.TryParse(tb.Text, out page))
{
if (page <= _pagedDataSource.PageCount && page > 0)
{
DiploGridView.PageIndex = page - 1;
}
}
}
}
/// <summary>
/// Handles the SelectedIndexChanged event of the ddlPageSize control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
void ddlPageSize_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList list = sender as DropDownList;
if (list != null) DiploGridView.PageSize = Convert.ToInt32(list.SelectedValue);
}
}
}
I can't really talk you through it as server controls are complex, I just hope it gives you some help.