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
Related
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.
I have a PulltoRefreshListView control:
public class PullToRefreshListView : ListView
{
private const string ScrollViewerControl = "ScrollViewer";
private const string ContainerGrid = "ContainerGrid";
private const string PullToRefreshIndicator = "PullToRefreshIndicator";
private const string RefreshButton = "RefreshButton";
private const string VisualStateNormal = "Normal";
private const string VisualStateReadyToRefresh = "ReadyToRefresh";
private DispatcherTimer compressionTimer;
private ScrollViewer scrollViewer;
private DispatcherTimer timer;
private Grid containerGrid;
private Border pullToRefreshIndicator;
private bool isCompressionTimerRunning;
private bool isReadyToRefresh;
private bool isCompressedEnough;
public event EventHandler RefreshContent;
public static readonly DependencyProperty PullTextProperty = DependencyProperty.Register("PullText", typeof(string), typeof(PullToRefreshListView), new PropertyMetadata("Pull to refresh"));
public static readonly DependencyProperty RefreshTextProperty = DependencyProperty.Register("RefreshText", typeof(string), typeof(PullToRefreshListView), new PropertyMetadata("Release to refresh"));
public static readonly DependencyProperty RefreshHeaderHeightProperty = DependencyProperty.Register("RefreshHeaderHeight", typeof(double), typeof(PullToRefreshListView), new PropertyMetadata(40D));
public static readonly DependencyProperty RefreshCommandProperty = DependencyProperty.Register("RefreshCommand", typeof(ICommand), typeof(PullToRefreshListView), new PropertyMetadata(null));
public static readonly DependencyProperty ArrowColorProperty = DependencyProperty.Register("ArrowColor", typeof(Brush), typeof(PullToRefreshListView), new PropertyMetadata(new SolidColorBrush(Colors.Red)));
private double offsetTreshhold = 40;
public PullToRefreshListView()
{
this.DefaultStyleKey = typeof(PullToRefreshListView);
Loaded += PullToRefreshScrollViewer_Loaded;
this.SizeChanged += PullToRefreshListView_SizeChanged;
}
private void PullToRefreshListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (ItemsPanelRoot != null)
ItemsPanelRoot.Width = e.NewSize.Width;
}
public ICommand RefreshCommand
{
get { return (ICommand)GetValue(RefreshCommandProperty); }
set { SetValue(RefreshCommandProperty, value); }
}
public double RefreshHeaderHeight
{
get { return (double)GetValue(RefreshHeaderHeightProperty); }
set { SetValue(RefreshHeaderHeightProperty, value); }
}
public string RefreshText
{
get { return (string)GetValue(RefreshTextProperty); }
set { SetValue(RefreshTextProperty, value); }
}
public string PullText
{
get { return (string)GetValue(PullTextProperty); }
set { SetValue(PullTextProperty, value); }
}
public Brush ArrowColor
{
get { return (Brush)GetValue(ArrowColorProperty); }
set { SetValue(ArrowColorProperty, value); }
}
protected override void OnApplyTemplate()
{
try
{
base.OnApplyTemplate();
scrollViewer = (ScrollViewer)GetTemplateChild(ScrollViewerControl);
scrollViewer.ViewChanging += ScrollViewer_ViewChanging;
scrollViewer.Margin = new Thickness(0, 0, 0, -RefreshHeaderHeight);
var transform = new CompositeTransform();
transform.TranslateY = -RefreshHeaderHeight;
scrollViewer.RenderTransform = transform;
containerGrid = (Grid)GetTemplateChild(ContainerGrid);
pullToRefreshIndicator = (Border)GetTemplateChild(PullToRefreshIndicator);
SizeChanged += OnSizeChanged;
}
catch (Exception wd)
{
var dwd = wd.Message;
}
}
/// <summary>
/// Initiate timers to detect if we're scrolling into negative space
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PullToRefreshScrollViewer_Loaded(object sender, RoutedEventArgs e)
{
// Show Refresh Button on non-touch device.
if (new Windows.Devices.Input.TouchCapabilities().TouchPresent == 0)
{
var refreshButton = (Button)GetTemplateChild(RefreshButton);
refreshButton.Visibility = Visibility.Visible;
refreshButton.Click += RefreshButton_Click;
}
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(100);
timer.Tick += Timer_Tick;
compressionTimer = new DispatcherTimer();
compressionTimer.Interval = TimeSpan.FromSeconds(.5);
compressionTimer.Tick += CompressionTimer_Tick;
timer.Start();
}
/// <summary>
/// Clip the bounds of the control to avoid showing the pull to refresh text
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
Clip = new RectangleGeometry()
{
Rect = new Rect(0, 0, e.NewSize.Width, e.NewSize.Height)
};
}
/// <summary>
/// Detect if we've scrolled all the way to the top. Stop timers when we're not completely in the top
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ScrollViewer_ViewChanging(object sender, ScrollViewerViewChangingEventArgs e)
{
if (e.NextView.VerticalOffset == 0)
{
timer.Start();
}
else
{
if (timer != null)
{
timer.Stop();
}
if (compressionTimer != null)
{
compressionTimer.Stop();
}
isCompressionTimerRunning = false;
isCompressedEnough = false;
isReadyToRefresh = false;
VisualStateManager.GoToState(this, VisualStateNormal, true);
}
}
/// <summary>
/// Detect if I've scrolled far enough and been there for enough time to refresh
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CompressionTimer_Tick(object sender, object e)
{
if (isCompressedEnough)
{
VisualStateManager.GoToState(this, VisualStateReadyToRefresh, true);
isReadyToRefresh = true;
}
else
{
isCompressedEnough = false;
compressionTimer.Stop();
}
}
/// <summary>
/// Invoke timer if we've scrolled far enough up into negative space. If we get back to offset 0 the refresh command and event is invoked.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Timer_Tick(object sender, object e)
{
if (containerGrid != null)
{
Rect elementBounds = pullToRefreshIndicator.TransformToVisual(containerGrid).TransformBounds(new Rect(0.0, 0.0, pullToRefreshIndicator.Height, RefreshHeaderHeight));
var compressionOffset = elementBounds.Bottom;
if (compressionOffset > offsetTreshhold)
{
if (isCompressionTimerRunning == false)
{
isCompressionTimerRunning = true;
compressionTimer.Start();
}
isCompressedEnough = true;
}
else if (compressionOffset == 0 && isReadyToRefresh == true)
{
InvokeRefresh();
}
else
{
isCompressedEnough = false;
isCompressionTimerRunning = false;
}
}
}
private void RefreshButton_Click(object sender, object e)
{
InvokeRefresh();
}
/// <summary>
/// Set correct visual state and invoke refresh event and command
/// </summary>
private void InvokeRefresh()
{
isReadyToRefresh = false;
VisualStateManager.GoToState(this, VisualStateNormal, true);
if (RefreshContent != null)
{
RefreshContent(this, EventArgs.Empty);
}
if (RefreshCommand != null && RefreshCommand.CanExecute(null) == true)
{
RefreshCommand.Execute(null);
}
}
}
and i use it in xaml:
<controls:PullToRefreshListView ItemsSource="{Binding TrackListItems}"
RefreshCommand="{Binding RefreshCommand}">
</controls:PullToRefreshListView>
and code behind:
refreshCommand = new RelayCommandN(RefreshItems);
public void RefreshItems()
{
TrackListItems.Clear();
//code: added my data in List: TrackListItems
}
In this way I always have new data, but the sheet is cleaned completely. How to do to the old data remain, and only add new data to the top of the list after "Pull To Refresh"?
What is the right strategy? I can find the data are marked as new. How to add them to the top of the list? And that there is no glitches? And do not clear the all list?
You can use List.Insert(0, newItem) to add items to the top of the list. If you want to add multiple items, you'll call have to use it multiple times. Note that calling Insert with 0 adds the items to the top of the list, which works if your items are in reverse order. If you want to add them in order, you can do something like this:
public void Refresh(ObservableCollection<Item> myList, List<Item> newItems)
{
for(int i = 0; i < newItems.Count; i++)
{
myList.Insert(i, newItem=newItems[i]);
}
}
I've created a method to update my GridControl. For my other GridControl I use the same method/constructor structure and I call it in the same way and it works. When I click the button which is in the same class as the update method the data in the grid is updated.But when I call this method (updateGridControl) from another usercontrol nothing happens to the GridControl. How to change my code that the method also updates the grid when I call it from another usercontrol/class?
This the call to the method:
incidentCategorySearchControl.Instance.updateGridControl(); // update doesn't work
incidentCategorySearchControl.cs
public partial class incidentCategorySearchControl : UserControl
{
public static incidentCategorySearchControl Instance { get; set; }
public incidentCategorySearchControl()
{
InitializeComponent();
Instance = this;
// This line of code is generated by Data Source Configuration Wizard
incIncidentCategoryTableAdapter1.Fill(reinvenT_QualityDataSet1.IncIncidentCategory);
bindingSource1.DataSource = reinvenT_QualityDataSet1;
}
public void updateGridControl()
{
incIncidentCategoryTableAdapter1.Fill(reinvenT_QualityDataSet1.IncIncidentCategory);
}
/// <summary>
/// GridControl row doubleclick handling
/// </summary>
/// <param name="view"></param>
/// <param name="pt"></param>
public void DoRowDoubleClick(GridView view, Point pt)
{
GridHitInfo info = view.CalcHitInfo(pt);
if (info.InRow || info.InRowCell)
{
try
{
string colCaption = info.Column == null ? "N/A" : info.Column.GetCaption();
Form1 myform = (Form1)this.categoryGridControl.FindForm();
int id = Convert.ToInt32(view.GetRowCellValue(info.RowHandle, "IncIncidentCategory"));
string description=view.GetRowCellValue(info.RowHandle,"IncIncidentCatDescription").ToString();
IncidentCategory incidentCategoryEditTarget = new IncidentCategory(id, description);
incidentCategoryChange.Instance.TextBoxCategory = incidentCategoryEditTarget._categoryId.ToString();
incidentCategoryChange.Instance.TextBoxCategoryDesc = incidentCategoryEditTarget._description;
XtraTabPage xtraTabPage = myform.xtraTabControl1.TabPages[3];
xtraTabPage.PageVisible = true;
myform.xtraTabControl1.SelectedTabPage = xtraTabPage;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
/// <summary>
/// CategoryGridControl double click event
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void categoryGridControl_DoubleClick(object sender, EventArgs e)
{
GridView view = (GridView)categoryGridControl.MainView;
Point pt = view.GridControl.PointToClient(Control.MousePosition);
DoRowDoubleClick(view, pt);
}
private void closeButton_Click(object sender, EventArgs e)
{
Form1 myform = (Form1)this.closeButton.FindForm();
myform.xtraTabControl1.SelectedTabPage.PageVisible = false;
}
private void addCategoryButton_Click_1(object sender, EventArgs e)
{
Form1 myform = (Form1)this.addCategoryButton.FindForm();
XtraTabPage xtraTabPage = myform.xtraTabControl1.TabPages[2];
xtraTabPage.PageVisible = true;
myform.xtraTabControl1.SelectedTabPage = xtraTabPage;
}
private void simpleButton1_Click(object sender, EventArgs e)
{
updateGridControl();
}
}
incidentCategoryChange.cs
namespace REINVENT.Quality
{
public partial class incidentCategoryChange : UserControl
{
public static incidentCategoryChange Instance { get; set; }
SqlCommand cmd = new SqlCommand();
public incidentCategoryChange()
{
InitializeComponent();
Instance = this;
// set no blinking
errorProvider1.BlinkStyle = ErrorBlinkStyle.NeverBlink;
}
//public property get/set incidentcategory
public string TextBoxCategory
{
get { return incidentCategoryTextBox.Text; }
set { incidentCategoryTextBox.Text = value; }
}
//public property get/set incidentcategory description
public string TextBoxCategoryDesc
{
get { return incidentCategoryDescTextBox.Text; }
set { incidentCategoryDescTextBox.Text = value; }
}
/// <summary>
/// Check if a control contains text
/// </summary>
/// <param name="control"><Control</param>
public void controlContainsText(Control control)
{
string errorMessage = "Dit veld mag niet leeg zijn";
if (control.Text.Trim().Length == 0)
errorProvider1.SetError(control, errorMessage);
else
errorProvider1.SetError(control, "");
}
private void closeCategoryChangeButton_Click(object sender, EventArgs e)
{
Form1 myform = (Form1)this.closeCategoryChangeButton.FindForm();
incidentCategoryDescTextBox.Enabled = true;
myform.xtraTabControl1.SelectedTabPage.PageVisible = false;
}
/// <summary>
/// Save the category to the database if the required fields are filled and update grids
/// </summary>
/// <param name="sender">sender object</param>
/// <param name="e">event</param>
private void saveCategoryChangeButton_Click(object sender, EventArgs e)
{
if (incidentCategoryDescTextBox.Text.Trim().Length == 0)
{
MessageBox.Show("Opslaan mislukt controleer a.u.b. of alle verplichte velden juist zijn ingevuld");
}
else
{
try
{
using (SqlConnection con = new SqlConnection(SqlServerConnection.sqlConnection.ConnectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand("UPDATE IncIncidentCategory SET IncIncidentCatDescription = #categoryDescription WHERE IncIncidentCategory = #categoryId", con))
{
IncidentCategory incidentCategoryUpdate = new IncidentCategory(Convert.ToInt32(incidentCategoryTextBox.Text), incidentCategoryDescTextBox.Text);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#categoryId", incidentCategoryUpdate._categoryId);
cmd.Parameters.AddWithValue("#categoryDescription", incidentCategoryUpdate._description);
cmd.ExecuteNonQuery();
MessageBox.Show("Wijzigingen opgeslagen");
}
}
incidentTypeChange.Instance.refreshCategorySearchBox();
incidentTypeMaintenance.Instance.refreshCategorySearchBox();
incidentCategorySearchControl.Instance.updateGridControl(); // update doesn't work
}
catch
{
MessageBox.Show("Voer voor beide velden geldige waarden in a.u.b.");
}
}
}
/// <summary>
/// Delete a category after confirmation of the user and update grids.
/// </summary>
/// <param name="sender">object sender</param>
/// <param name="e">event</param>
private void deleteCategoryButton_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Weet u zeker dat u deze categorie wilt verwijderen?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
try
{
using (SqlConnection con = new SqlConnection(SqlServerConnection.sqlConnection.ConnectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand("DELETE FROM IncIncidentCategory WHERE IncIncidentCategory = #idDelete", con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#idDelete", Convert.ToInt32(incidentCategoryTextBox.Text));
cmd.ExecuteNonQuery();
}
}
incidentCategoryTextBox.Text = "";
incidentCategoryDescTextBox.Text = "";
MessageBox.Show("De categorie is verwijderd");
incidentTypeChange.Instance.refreshCategorySearchBox();
incidentTypeMaintenance.Instance.refreshCategorySearchBox();
}
catch
{
MessageBox.Show("Voer voor beide velden geldige waarden in a.u.b. Verwijzingen naar deze catergorie dienen eerst verwijderd/aangepast te worden");
}
}
}
private void incidentCategoryDescTextBox_Validating(object sender, CancelEventArgs e)
{
controlContainsText(incidentCategoryDescTextBox);
}
private void newCategoryButton_Click(object sender, EventArgs e)
{
Form1 myform = (Form1)this.newCategoryButton.FindForm();
XtraTabPage xtraTabPage = myform.xtraTabControl1.TabPages[2];
xtraTabPage.PageVisible = true;
myform.xtraTabControl1.SelectedTabPage = xtraTabPage;
}
}
}
I was wondering if anyone could show me a simple way of creating buttons in XNA.
Preferably a way to add a function when its clicked, and a way to add and remove them easily.
I recommend using the NeoForce Controls Library for GUI related problems - it has buttons, among the other useful GUI controls including popup windows, list views, combo boxes, and so on.
If you are writing a button class for the learning experience... well, try learning more about it yourself via Google before asking for help.
ADDENDUM
This is some code that I've written for buttons. Maybe it can serve as a starting point. I use it in my 2D game engine, so it has been debugged and tested.
/// <summary>
/// A control that changes appearance when it is hovered over and triggers some effect when it is clicked
/// </summary>
public class EnigmaButton
{
/// <summary>
/// The method signature for notification when a button is clicked
/// </summary>
/// <param name="sender">EnigmaButton that was clicked</param>
public delegate void OnClickEvent(EnigmaButton sender);
/// <summary>
/// Types of textures used for Enigma Buttons
/// </summary>
public enum TextureType { Normal, Over, Press }
#region Variables
protected IVisualExposer m_ui;
protected Rectangle m_bounds;
IInputExposer m_input;
bool m_over = false, m_press = false, m_wasPressed = false;
Dictionary<TextureType, EnigmaResource<Texture2D>> m_textures;
string m_text, m_name;
EnigmaResource<SpriteFont> m_font;
int m_minTextShadow, m_maxTextShadow;
Color m_textTint;
public event OnClickEvent OnClick;
#endregion
/// <summary>
/// A control that changes appearance when it is hovered over and triggers some effect when it is clicked
/// </summary>
/// <param name="ui">Graphical assets</param>
/// <param name="input">Input exposer for mouse input and XBox controller input</param>
/// <param name="reader">XMLReader for the definition of the controller</param>
/// <param name="pos">Bounds of the controller</param>
public EnigmaButton(IVisualExposer ui, IInputExposer input, XmlReader reader, Rectangle pos)
{
m_ui = ui;
m_bounds = pos;
m_textures = new Dictionary<TextureType, EnigmaResource<Texture2D>>();
m_input = input;
Enabled = true;
#region Reading
string name;
bool started = false, insideText = false;
while (reader.Read())
{
if (reader.MoveToContent() == XmlNodeType.Element)
{
name = reader.Name.ToLower();
if (name == "button")
{
if (started)
throw new Exception("Already started.");
started = true;
m_name = reader.GetAttribute("name") ?? string.Empty;
}
else if (!started)
throw new Exception("Not started");
else if (name == "text")
{
m_font = new EnigmaResource<SpriteFont>();
m_font.Filepath = reader.GetAttribute("font");
string minShadow = reader.GetAttribute("minShadow"), maxShadow = reader.GetAttribute("maxShadow");
m_minTextShadow = minShadow != null ? int.Parse(minShadow) : 0;
m_maxTextShadow = maxShadow != null ? int.Parse(maxShadow) : 2;
m_text = reader.GetAttribute("text") ?? string.Empty;
insideText = true;
m_textTint = Color.White;
}
else if (name == "bounds")
{
insideText = false;
m_bounds = new Rectangle(int.Parse(reader.GetAttribute("x")), int.Parse(reader.GetAttribute("y")),
int.Parse(reader.GetAttribute("width")), int.Parse(reader.GetAttribute("height")));
}
else if (name == "texture")
{
insideText = false;
TextureType texType = (TextureType)Enum.Parse(typeof(TextureType), reader.GetAttribute("type"));
if (m_textures.ContainsKey(texType))
throw new Exception("A texture of type '" + texType.ToString() + "' cannot be registered twice");
EnigmaResource<Texture2D> res = new EnigmaResource<Texture2D>();
res.Filepath = reader.ReadString();
m_textures.Add(texType, res);
}
else if (name == "tint")
{
if (!insideText)
throw new Exception("Tints can only be for text");
float a, r, g, b;
string[] split = reader.ReadString().Split(',');
if (split.Length != 4)
throw new Exception("Colors must be RGBA");
r = float.Parse(split[0].Trim());
g = float.Parse(split[1].Trim());
b = float.Parse(split[2].Trim());
a = float.Parse(split[3].Trim());
m_textTint = new Color(r, g, b, a);
}
}
}
#endregion
if (!m_textures.ContainsKey(TextureType.Normal))
throw new Exception("A button must have at least a '" + TextureType.Normal.ToString() + "' texture");
}
#region Methods
public void Initialize()
{
}
public void LoadContent()
{
EnigmaResource<Texture2D> res;
for (int i = 0; i < m_textures.Count; i++)
{
res = m_textures[m_textures.ElementAt(i).Key];
res.Resource = m_ui.Content.Load<Texture2D>(res.Filepath);
m_textures[m_textures.ElementAt(i).Key] = res;
}
if (m_font.Filepath != null)
m_font.Resource = m_ui.Content.Load<SpriteFont>(m_font.Filepath);
}
public void Update(GameTime gameTime)
{
m_wasPressed = m_press;
m_over = m_bounds.Contains(m_input.MouseX, m_input.MouseY);
m_press = m_over ? m_wasPressed ? m_input.IsMouseLeftPressed || m_input.IsButtonPressed(Buttons.A) : m_input.IsMouseLeftTriggered || m_input.IsButtonTriggered(Buttons.A) : false;
if (!m_wasPressed && m_press && OnClick != null)
OnClick(this);
}
public void Draw(GameTime gameTime)
{
Texture2D toDraw = m_textures[TextureType.Normal].Resource;
if (Enabled)
{
if (m_press && m_textures.ContainsKey(TextureType.Press))
toDraw = m_textures[TextureType.Press].Resource;
else if (m_over && m_textures.ContainsKey(TextureType.Over))
toDraw = m_textures[TextureType.Over].Resource;
}
m_ui.SpriteBatch.Draw(toDraw, m_bounds, Enabled ? Color.White : Color.Gray);
if (m_font.Resource != null)
{
Vector2 pos = new Vector2(m_bounds.X, m_bounds.Y);
Vector2 size = m_font.Resource.MeasureString(m_text);
pos.X += (m_bounds.Width - size.X) / 2;
pos.Y += (m_bounds.Height - size.Y) / 2;
UIHelper.DrawShadowedString(m_ui, m_font.Resource, m_text, pos, m_textTint, m_minTextShadow, m_maxTextShadow);
}
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the name of the button
/// </summary>
public string Name
{
get { return m_name; }
set { m_name = value ?? m_name; }
}
/// <summary>
/// Gets or sets the text drawn in the button.
/// WARNING: Will overflow if the text does not normally fit.
/// </summary>
public string Text
{
get { return m_text; }
set { m_text = value ?? string.Empty; }
}
/// <summary>
/// Gets or sets the bounds of the button
/// </summary>
public Rectangle Bounds
{
get { return m_bounds; }
set { m_bounds = value; }
}
/// <summary>
/// Whether or not the control is enabled
/// </summary>
public bool Enabled { get; set; }
#endregion
}
I have made a GIF Animation user control which loads gif animations and have created about 30 of them in my project each animating a GIF. The problem is that when I check my CPU usage it is about 70%+!!! I'm sure something is wrong with this!
Please help me. Here is the code of that GIF Animator control:
public class AnimatedImage : System.Windows.Controls.Image
{
private BitmapSource[] _BitmapSources = null;
private int _nCurrentFrame=0;
private bool _bIsAnimating=false;
public bool IsAnimating
{
get { return _bIsAnimating; }
}
static AnimatedImage()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(AnimatedImage), new FrameworkPropertyMetadata(typeof(AnimatedImage)));
}
public Bitmap AnimatedBitmap
{
get { return (Bitmap)GetValue(AnimatedBitmapProperty); }
set { StopAnimate(); SetValue(AnimatedBitmapProperty, value); }
}
/// <summary>
/// Identifies the Value dependency property.
/// </summary>
public static readonly DependencyProperty AnimatedBitmapProperty =
DependencyProperty.Register(
"AnimatedBitmap", typeof(Bitmap), typeof(AnimatedImage),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnAnimatedBitmapChanged)));
private static void OnAnimatedBitmapChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
AnimatedImage control = (AnimatedImage)obj;
control.UpdateAnimatedBitmap();
RoutedPropertyChangedEventArgs<Bitmap> e = new RoutedPropertyChangedEventArgs<Bitmap>(
(Bitmap)args.OldValue, (Bitmap)args.NewValue, AnimatedBitmapChangedEvent);
control.OnAnimatedBitmapChanged(e);
}
/// <summary>
/// Identifies the ValueChanged routed event.
/// </summary>
public static readonly RoutedEvent AnimatedBitmapChangedEvent = EventManager.RegisterRoutedEvent(
"AnimatedBitmapChanged", RoutingStrategy.Bubble,
typeof(RoutedPropertyChangedEventHandler<Bitmap>), typeof(AnimatedImage));
/// <summary>
/// Occurs when the Value property changes.
/// </summary>
public event RoutedPropertyChangedEventHandler<Bitmap> AnimatedBitmapChanged
{
add { AddHandler(AnimatedBitmapChangedEvent, value); }
remove { RemoveHandler(AnimatedBitmapChangedEvent, value); }
}
/// <summary>
/// Raises the ValueChanged event.
/// </summary>
/// <param name="args">Arguments associated with the ValueChanged event.</param>
protected virtual void OnAnimatedBitmapChanged(RoutedPropertyChangedEventArgs<Bitmap> args)
{
RaiseEvent(args);
}
private void UpdateAnimatedBitmap()
{
int nTimeFrames = AnimatedBitmap.GetFrameCount(System.Drawing.Imaging.FrameDimension.Time);
_nCurrentFrame = 0;
if (nTimeFrames > 0)
{
_BitmapSources = new BitmapSource[nTimeFrames];
for (int i = 0; i < nTimeFrames; i++)
{
AnimatedBitmap.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Time, i);
Bitmap bitmap = new Bitmap(AnimatedBitmap);
bitmap.MakeTransparent();
_BitmapSources[i] = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
bitmap.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
}
StartAnimate();
}
}
private delegate void VoidDelegate();
private void OnFrameChanged(object o, EventArgs e)
{
Dispatcher.BeginInvoke(DispatcherPriority.Render, new VoidDelegate(delegate { ChangeSource(); }));
}
void ChangeSource()
{
Source = _BitmapSources[_nCurrentFrame++];
_nCurrentFrame = _nCurrentFrame % _BitmapSources.Length;
ImageAnimator.UpdateFrames();
}
public void StopAnimate()
{
if (_bIsAnimating)
{
ImageAnimator.StopAnimate(AnimatedBitmap, new EventHandler(this.OnFrameChanged));
_bIsAnimating = false;
}
}
public void StartAnimate()
{
if (!_bIsAnimating)
{
ImageAnimator.Animate(AnimatedBitmap, new EventHandler(this.OnFrameChanged));
_bIsAnimating = true;
}
}
}
}
Give this one a shot. We've used it in our application and I haven't notice any weird memory consumption.