I have an Excel template that has a table (range: A4:AM5) which I need to expand by inserting rows via EPPlus. My code inserts the cell values in the file with no problem, but I need to extend the rows of the table according to each new value inserted in the first column.
I tried to use the InsertRow(5,1) method but it shows an exception
"System.ArgumentOutOfRangeException: 'Row cannot be less than 1.
Parameter name: value'"
And the value presents:
{System.ArgumentOutOfRangeException: Row cannot be less than 1. Parameter name: value > at OfficeOpenXml.ExcelCellAddress.set_Row(Int32 value) > at OfficeOpenXml.ExcelNamedRangeCollection.InsertRows(Int32 rowFrom, Int32 rows, ExcelNamedRange namedRange) > at OfficeOpenXml.ExcelNamedRangeCollection.Insert(Int32 rowFrom, Int32 colFrom, Int32 rows, Int32 cols, Func`2 filter) > at OfficeOpenXml.ExcelWorksheet.InsertRow(Int32 rowFrom, Int32 rows, Int32 copyStylesFromRow) > at TestInsertRow.Program.Main(String[] args)}
I minimized the functions of the code into this one which also shows the same exception:
class Dnp3
{
private static ExcelPackage _dnp3Package;
private static ExcelWorksheet _worksheet1;
private static FileInfo _templateInfo;
private static FileInfo _newDnp3FileInfo;
public static bool TempFile
{
get
{
if (_templateInfo != null) return true;
return false;
}
set
{
if (value == true)
{
_templateInfo = new FileInfo(#" Existing template path ");
}
}
}
public static bool NewFile
{
get
{
if (_newDnp3FileInfo != null) return true;
return false;
}
set
{
if (value == true)
{
_newDnp3FileInfo = new FileInfo(#" Existing new file path ");
_dnp3Package = new ExcelPackage(_newDnp3FileInfo, _templateInfo);
{
_worksheet1 = Dnp3._dnp3Package.Workbook.Worksheets["DNP3_RTUs"];
{
_worksheet1.DataValidations.Clear();
}
}
}
}
}
public static bool Save
{
set
{
if (value == true)
{
Dnp3._dnp3Package.Save();
}
}
}
public class DNP3_RTUs : Dnp3
{
private int _idobj_nameCol;//IDOBJ_NAME
private int _idobj_aliasCol;//IDOBJ_ALIAS
private int _idobj_customidCol;//IDOBJ_CUSTOMID
private int _idobj_aorgroupCol;//IDOBJ_AORGROUP
public bool Header
{
set
{
int _column = 1;
_idobj_nameCol = 1;
_idobj_aliasCol = 1;
_idobj_customidCol = 1;
_idobj_aorgroupCol = 1;
if (value == true)
{
while (_worksheet1.Cells[Row: 3, Col: _column].Value != null)
{
switch (_worksheet1.Cells[Row: 3, Col: _column].Value)
{
case "IDOBJ_NAME":
_idobj_nameCol = _column;
break;
case "IDOBJ_ALIAS":
_idobj_aliasCol = _column;
break;
case "IDOBJ_CUSTOMID":
_idobj_customidCol = _column;
break;
case "IDOBJ_AORGROUP":
_idobj_aorgroupCol = _column;
break;
}
_column++;
}
}
}
}
public bool AddRow(int _line)
{
_line = _line + 5;
_worksheet1.InsertRow(_line, 2);
return false;
}
public string IDOBJ_NAME(int _line, string _data)
{
_line = _line + 5;//Pq a entrada de dados começa na linha
_worksheet1.Cells[_line, _idobj_nameCol].Value = _data;
_worksheet1.Cells[_line, _idobj_nameCol].Style.Font.Size = 11;
_worksheet1.Cells[_line, _idobj_nameCol].Style.Font.Name = "Calibri";
return "";
}
public string IDOBJ_ALIAS(int _line, string _data)
{
_line = _line + 5;//Pq a entrada de dados começa na linha 5
_worksheet1.Cells[_line, _idobj_aliasCol].Value = _data;
_worksheet1.Cells[_line, _idobj_aliasCol].Style.Font.Size = 11;
_worksheet1.Cells[_line, _idobj_aliasCol].Style.Font.Name = "Calibri";
return "";
}
public string IDOBJ_CUSTOMID(int _line, string _data)
{
_line = _line + 5;//Pq a entrada de dados começa na linha 5
_worksheet1.Cells[_line, _idobj_customidCol].Value = _data;
_worksheet1.Cells[_line, _idobj_customidCol].Style.Font.Size = 11;
_worksheet1.Cells[_line, _idobj_customidCol].Style.Font.Name = "Calibri";
return "";
}
public string IDOBJ_AORGROUP(int _line, string _data)
{
_line = _line + 5;//Pq a entrada de dados começa na linha 5
_worksheet1.Cells[_line, _idobj_aorgroupCol].Value = _data;
_worksheet1.Cells[_line, _idobj_aorgroupCol].Style.Font.Size = 11;
_worksheet1.Cells[_line, _idobj_aorgroupCol].Style.Font.Name = "Calibri";
return "";
}
}
}
class Program
{
static void Main(string[] args)
{
Dnp3.TempFile = true;
Dnp3.NewFile = true;
Dnp3.DNP3_RTUs dNP3_RTUs = new Dnp3.DNP3_RTUs() { Header = true };
int _mappingCount = 1;
dNP3_RTUs.IDOBJ_NAME(_mappingCount, "BOQ_1");
dNP3_RTUs.IDOBJ_ALIAS(_mappingCount,"nome_se_ordem");
dNP3_RTUs.IDOBJ_AORGROUP(_mappingCount, "mnem_se");
dNP3_RTUs.AddRow(_mappingCount);
Dnp3.Save = true;
}
}
I faced the same exception and was able to resolve it by fixing the excel template names collection.
Press Ctrl+F3 (Name Manager) and search for names containing any #REF! values and referrers and delete them from the template.
If Ctrl + F3 doesn't work for finding Name Manager
Hover over "sheet.Names" you will find all Name Managers And
you can remove them throw code
var refName = sheet.Names.FirstOrDefault(x => x.Name == "nameOfNameManager");
if (refName != null)
{
sheet.Names.Remove("nameOfNameManager");
}
Related
I have populated a listview by Just In Time Data loading according to
https://learn.microsoft.com/en-us/dotnet/framework/winforms/controls/virtual-mode-with-just-in-time-data-loading-in-the-datagrid
and
https://learn.microsoft.com/en-us/dotnet/framework/winforms/controls/implementing-virtual-mode-jit-data-loading-in-the-datagrid
Now I want to sort on columnClick of list view . I don't have any clue how should I do that
I have done like this
Cache Class
public class Cache
{
private static int RowsPerPage;
// Represents one page of data.
public struct DataPage
{
public DataTable table;
private int lowestIndexValue;
private int highestIndexValue;
public DataPage(DataTable table, int rowIndex)
{
this.table = table;
lowestIndexValue = MapToLowerBoundary(rowIndex);
highestIndexValue = MapToUpperBoundary(rowIndex);
System.Diagnostics.Debug.Assert(lowestIndexValue >= 0);
System.Diagnostics.Debug.Assert(highestIndexValue >= 0);
}
public int LowestIndex
{
get
{
return lowestIndexValue;
}
}
public int HighestIndex
{
get
{
return highestIndexValue;
}
}
public static int MapToLowerBoundary(int rowIndex)
{
// Return the lowest index of a page containing the given index.
return (rowIndex / RowsPerPage) * RowsPerPage;
}
private static int MapToUpperBoundary(int rowIndex)
{
// Return the highest index of a page containing the given index.
return MapToLowerBoundary(rowIndex) + RowsPerPage - 1;
}
}
private DataPage[] cachePages;
private IDataPageRetriever dataSupply;
public Cache(IDataPageRetriever dataSupplier, int rowsPerPage)
{
dataSupply = dataSupplier;
Cache.RowsPerPage = rowsPerPage;
LoadFirstTwoPages();
}
public IDataPageRetriever DataSupplier
{
get
{
return dataSupply;
}
}
// Sets the value of the element parameter if the value is in the cache.
private bool IfPageCached_ThenSetElement(int rowIndex,
int columnIndex, ref object element)
{
if (IsRowCachedInPage(0, rowIndex))
{
element = cachePages[0].table
.Rows[rowIndex % RowsPerPage][columnIndex];
return true;
}
else if (IsRowCachedInPage(1, rowIndex))
{
element = cachePages[1].table
.Rows[rowIndex % RowsPerPage][columnIndex];
return true;
}
return false;
}
private bool IfPageCached_ThenSetElement(int rowIndex,
string columnName, ref object element)
{
if (IsRowCachedInPage(0, rowIndex))
{
element = cachePages[0].table
.Rows[rowIndex % RowsPerPage][columnName];
return true;
}
else if (IsRowCachedInPage(1, rowIndex))
{
element = cachePages[1].table
.Rows[rowIndex % RowsPerPage][columnName];
return true;
}
return false;
}
public object RetrieveElement(int rowIndex, int columnIndex)
{
object element = null;
if (IfPageCached_ThenSetElement(rowIndex, columnIndex, ref element))
{
return element;
}
else
{
return RetrieveData_CacheIt_ThenReturnElement(
rowIndex, columnIndex);
}
}
public object RetrieveElement(int rowIndex, string columnName)
{
object element = null;
if (IfPageCached_ThenSetElement(rowIndex, columnName, ref element))
{
return element;
}
else
{
return RetrieveData_CacheIt_ThenReturnElement(
rowIndex, columnName);
}
}
public void RemoveElement(int rowIndex)
{
if (IsRowCachedInPage(0, rowIndex))
{
cachePages[0].table.Rows.RemoveAt(rowIndex % RowsPerPage);
}
else if (IsRowCachedInPage(1, rowIndex))
{
cachePages[1].table.Rows.RemoveAt(rowIndex % RowsPerPage);
}
}
private void LoadFirstTwoPages()
{
cachePages = new DataPage[]{
new DataPage(dataSupply.SupplyPageOfData(
DataPage.MapToLowerBoundary(0), RowsPerPage), 0),
new DataPage(dataSupply.SupplyPageOfData(
DataPage.MapToLowerBoundary(RowsPerPage),
RowsPerPage), RowsPerPage)};
}
private object RetrieveData_CacheIt_ThenReturnElement(
int rowIndex, int columnIndex)
{
// Retrieve a page worth of data containing the requested value.
DataTable table = dataSupply.SupplyPageOfData(
DataPage.MapToLowerBoundary(rowIndex), RowsPerPage);
// Replace the cached page furthest from the requested cell
// with a new page containing the newly retrieved data.
cachePages[GetIndexToUnusedPage(rowIndex)] = new DataPage(table, rowIndex);
return RetrieveElement(rowIndex, columnIndex);
}
private object RetrieveData_CacheIt_ThenReturnElement(
int rowIndex, string columnName)
{
// Retrieve a page worth of data containing the requested value.
DataTable table = dataSupply.SupplyPageOfData(
DataPage.MapToLowerBoundary(rowIndex), RowsPerPage);
// Replace the cached page furthest from the requested cell
// with a new page containing the newly retrieved data.
cachePages[GetIndexToUnusedPage(rowIndex)] = new DataPage(table, rowIndex);
return RetrieveElement(rowIndex, columnName);
}
// Returns the index of the cached page most distant from the given index
// and therefore least likely to be reused.
private int GetIndexToUnusedPage(int rowIndex)
{
if (rowIndex > cachePages[0].HighestIndex &&
rowIndex > cachePages[1].HighestIndex)
{
int offsetFromPage0 = rowIndex - cachePages[0].HighestIndex;
int offsetFromPage1 = rowIndex - cachePages[1].HighestIndex;
if (offsetFromPage0 < offsetFromPage1)
{
return 1;
}
return 0;
}
else
{
int offsetFromPage0 = cachePages[0].LowestIndex - rowIndex;
int offsetFromPage1 = cachePages[1].LowestIndex - rowIndex;
if (offsetFromPage0 < offsetFromPage1)
{
return 1;
}
return 0;
}
}
// Returns a value indicating whether the given row index is contained
// in the given DataPage.
private bool IsRowCachedInPage(int pageNumber, int rowIndex)
{
return rowIndex <= cachePages[pageNumber].HighestIndex &&
rowIndex >= cachePages[pageNumber].LowestIndex;
}
}
And this is the DataRetriever:
public class DataRetriever : IDataPageRetriever
{
private string tableName;
private string whereClause;
private KeyValuePair<string, object>[] parameters;
public DataRetriever(string tableName, DataTable tableSchema, string whereClause, KeyValuePair<string, object>[] parameters)
{
this.tableName = tableName;
this.whereClause = whereClause;
this.parameters = parameters;
this.tableSchema = tableSchema;
}
private int rowCountValue = -1;
private DataTable tableSchema;
public int RowCount
{
get
{
// Return the existing value if it has already been determined.
if (rowCountValue != -1)
{
return rowCountValue;
}
StringBuilder sql = new StringBuilder("SELECT COUNT(*) FROM " + tableName);
if (!string.IsNullOrEmpty(whereClause))
sql.Append(" WHERE " + whereClause);
// Retrieve the row count from the database.
using (ECartableServiceClient client = new ECartableServiceClient())
{
rowCountValue = client.GetRowCount(sql.ToString(), parameters);
client.Close();
}
return rowCountValue;
}
}
private DataColumnCollection columnsValue;
public DataColumnCollection Columns
{
get
{
if (columnsValue == null)
{
if (tableSchema == null)
{
// Retrieve the column information from the database.
using (ECartableServiceClient client = new ECartableServiceClient())
{
columnsValue = client.GetTableSchema("SELECT * FROM " + tableName).Columns;
client.Close();
}
}
else
columnsValue = tableSchema.Columns;
}
return columnsValue;
}
}
private string commaSeparatedListOfColumnNamesValue = null;
private string CommaSeparatedListOfColumnNames
{
get
{
// Return the existing value if it has already been determined.
if (commaSeparatedListOfColumnNamesValue != null)
{
return commaSeparatedListOfColumnNamesValue;
}
// Store a list of column names for use in the
// SupplyPageOfData method.
System.Text.StringBuilder commaSeparatedColumnNames =
new System.Text.StringBuilder();
bool firstColumn = true;
foreach (DataColumn column in Columns)
{
if (!firstColumn)
{
commaSeparatedColumnNames.Append(", ");
}
commaSeparatedColumnNames.Append(column.ColumnName);
firstColumn = false;
}
commaSeparatedListOfColumnNamesValue =
commaSeparatedColumnNames.ToString();
return commaSeparatedListOfColumnNamesValue;
}
}
// Declare variables to be reused by the SupplyPageOfData method.
private string columnToSortBy;
public DataTable SupplyPageOfData(int lowerPageBoundary, int rowsPerPage)
{
// Store the name of the ID column. This column must contain unique
// values so the SQL below will work properly.
if (columnToSortBy == null)
{
columnToSortBy = this.Columns[0].ColumnName;
}
if (!this.Columns[columnToSortBy].Unique)
{
throw new InvalidOperationException(String.Format(
"Column {0} must contain unique values.", columnToSortBy));
}
// Retrieve the specified number of rows from the database, starting
// with the row specified by the lowerPageBoundary parameter.
DataTable table;
string sql = "declare #maxId int\n" +
"SELECT #maxId = MAX(" + columnToSortBy + ") FROM (SELECT TOP " + lowerPageBoundary + " " + columnToSortBy + " FROM " + tableName.Replace("*", "Id") + (string.IsNullOrEmpty(whereClause) ? "" : " WHERE " + whereClause) + " ORDER BY " + columnToSortBy + ") AS t2\n" +
"SELECT TOP " + rowsPerPage + " " +
CommaSeparatedListOfColumnNames + " FROM " + tableName +
" WHERE " + (string.IsNullOrEmpty(whereClause) ? "" : whereClause + " AND ") + columnToSortBy + " > case when #maxId is null then 0 else #maxId end ORDER BY " + columnToSortBy;
using (ECartableServiceClient client = new ECartableServiceClient())
{
table = client.GetDataTable(tableSchema, sql, parameters);
client.Close();
}
return table;
}
}
and this is what I do to call the data
if (LoadData("vwUser", null, "Users", 50, searchCriteria, null))
ShowData("Users");
private bool LoadData(string tableName, DataTable tableSchema, string cacheName, int rowsPerPage, string criteria, KeyValuePair<string, object>[] parameters)
{
bool result = true;
object[] arguments = new object[6] { tableName, tableSchema, cacheName, rowsPerPage, criteria, parameters };
if (!dictionaryCaches.ContainsKey(cacheName))
{
try
{
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync(arguments);
formWait = new FormWait();
formWait.ShowDialog(this);
}
catch (System.Data.SqlClient.SqlException)
{
result = false;
MessageBox.Show("Connection could not be established. " +
"Verify that the connection string is valid.");
Application.Exit();
}
}
return result;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker worker = sender as BackgroundWorker;
object[] arguments = (object[])e.Argument;
DataRetriever retriever =
new DataRetriever((string)arguments[0], (DataTable)arguments[1], (string)arguments[4], (KeyValuePair<string, object>[])arguments[5]); //"Date_Received >= #d", new KeyValuePair<string, object>[] { new KeyValuePair<string, object>("#d", DateTime.Today) });
dictionaryCaches.Add((string)arguments[2], new Cache(retriever, (int)arguments[3]));
int rowCount = retriever.RowCount;
}
how Can I sort the listView by ColumnCLick?
Based on my test, I can not run your code successfully.
However, I can use the following code to load the data in time and sort the listview by column click.
Code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string connectionstring = #"connectionstring";
SqlConnection connection = new SqlConnection(connectionstring);
connection.Open();
string sql = "select * from Student";
SqlDataAdapter adapter = new SqlDataAdapter(sql,connection);
DataSet dataset = new DataSet();
adapter.Fill(dataset);
DataTable table = dataset.Tables[0];
List<string> list = new List<string>();
listView1.View = View.Details;
foreach (DataColumn item in table.Columns)
{
listView1.Columns.Add(item.ColumnName);
}
foreach (DataRow row in table.Rows)
{
ListViewItem listitem = new ListViewItem(row[0].ToString());
listitem.SubItems.Add(row[1].ToString());
listitem.SubItems.Add(row[2].ToString());
listView1.Items.Add(listitem);
}
}
private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
{
ListViewSorter Sorter = new ListViewSorter();
listView1.ListViewItemSorter = Sorter;
if (!(listView1.ListViewItemSorter is ListViewSorter))
return;
Sorter = (ListViewSorter)listView1.ListViewItemSorter;
if (Sorter.LastSort == e.Column)
{
if (listView1.Sorting == SortOrder.Ascending)
listView1.Sorting = SortOrder.Descending;
else
listView1.Sorting = SortOrder.Ascending;
}
else
{
listView1.Sorting = SortOrder.Descending;
}
Sorter.ByColumn = e.Column;
listView1.Sort();
}
}
public class ListViewSorter : System.Collections.IComparer
{
public int Compare(object o1, object o2)
{
if (!(o1 is ListViewItem))
return (0);
if (!(o2 is ListViewItem))
return (0);
ListViewItem lvi1 = (ListViewItem)o2;
string str1 = lvi1.SubItems[ByColumn].Text;
ListViewItem lvi2 = (ListViewItem)o1;
string str2 = lvi2.SubItems[ByColumn].Text;
int result;
if (lvi1.ListView.Sorting == SortOrder.Ascending)
result = String.Compare(str1, str2);
else
result = String.Compare(str2, str1);
LastSort = ByColumn;
return (result);
}
public int ByColumn
{
get
{
return Column;
}
set
{
Column = value;
}
}
int Column = 0;
public int LastSort
{
get
{
return LastColumn;
}
set
{
LastColumn = value;
}
}
int LastColumn = 0;
}
Result:
This image shows what happens after type the name smith and press button searchI have a CSV text file full of data that is loaded in to an array and displayed in a listview. It has multiple columns and rows. The Columns are ext code, forename, surname. Each row is a different record. I have created a text box that will allow the user to input the surname of a record. Then a search button will allow the user to search on surname for extension number. Ideally the program should cope with multiple employees with the same surname, and match on just the first part of the surname; e.g. Sm for Smith and Smyth. It is a basic requirement that searching is not case sensitive.
A binary Search has to be used.
There are two methods that i tried, however i don't fully understand.
The button should only call the function.
Below is what I have tried, however it is not correct. Help will be greatly appreciated.
private void searchName()
{
Array.Sort(partsTable, (x, y) => string.Compare(x.surname, y.surname));
Clear();
int nameIndex = binarySearch(partsTable, txtSurname.Text);
ListViewItem phone = new ListViewItem();
phone.Text = (Convert.ToString(partsTable[nameIndex].surname));
phone.SubItems.Add(Convert.ToString(partsTable[nameIndex].forename));
phone.SubItems.Add(Convert.ToString(partsTable[nameIndex].extensionCode));
lstOutput.Items.Add(phone);
}
private int binarySearch(phone[] partsTable, string Key)
{
/* int left = 0;
int right = partsTable.Length - 1;
int nameIndex = -1;
bool found = false;
while (found != true && left <= right)
{
int mid = (left + right) / 2;
if (string.Compare(partsTable[mid].surname, Key, true) == 0)
{
found = true;
nameIndex = mid;
MessageBox.Show("If 1");
}
else if (string.Compare(partsTable[mid].surname, Key, true) > 0)
{
right = mid;
MessageBox.Show("If 2");
}
else
{
left = mid;
MessageBox.Show("If 3");
}
}
return nameIndex;
*/
/* while (left <= right)
{
if (left > right)
{
MessageBox.Show("Search Failed");
}
else
{
int mid = (left + right) / 2;
if (Key == partsTable[mid].surname)
return mid;
else if (String.Compare(Key, partsTable[mid].surname) < 0)
right = mid - 1;
else
left = mid + 1;
}
}
return -2;
*/
}
private void btnSearch_Click(object sender, EventArgs e)
{
string Key = txtSurname.Text;
int answer = binarySearch(partsTable, Key);
textBox1.Text = Convert.ToString(answer);
if (answer >= -1)
{
string message = "Extension code already in use";
string title = "Error";
MessageBox.Show(message, title);
extensionCode.Text = string.Empty;
forename.Text = string.Empty;
surname.Text = string.Empty;
lstOutput.Items.Clear();
}
}
Here is a simple demo that uses a list to store temp variable(table data). And then use "do ... while" to traverse the list.
private void btSearch_Click(object sender, EventArgs e)
{
lstOutput.Items.Clear();
do
{
searchName();
if (index != -1)
{
people.RemoveAt(index);
}
}
while (!isnull);
}
List<Person> people = new List<Person> {
new Person { No = 1, Surname = "Smith"} ,
new Person { No = 2, Surname = "Smit"},
new Person { No = 3, Surname = "Bob"},
new Person { No = 4, Surname = "KKK"},
new Person { No = 5, Surname = "Obt"},
new Person { No = 6, Surname = "Peter"}};
private void Form1_Load(object sender, EventArgs e)
{
lstOutput.View = View.Details;
people.Sort((x, y) => { return x.Surname.CompareTo(y.Surname); });
}
bool isnull = false;
int index;
private void searchName()
{
index = BinarySearch(people, 0, people.Count, txtSurname.Text);
if (index != -1)
{
ListViewItem phone = new ListViewItem();
phone.Text = (Convert.ToString(people[index].No));
phone.SubItems.Add(Convert.ToString(people[index].Surname));
lstOutput.Items.Add(phone);
}
else
{
isnull = true;
}
}
List<int> list = new List<int>();
private int BinarySearch(List<Person> p, int low, int high, string key)
{
int mid = (low + high) / 2;
if (low > high)
return -1;
else
{
try
{
string str = p[mid].Surname.Substring(0, key.Length);
if (string.Compare(str, key) == 0)
return mid;
else if (string.Compare(str, key) > 0)
return BinarySearch(p, low, mid - 1, key);
else
return BinarySearch(p, mid + 1, high, key);
}
catch
{
return -1;
}
}
}
class Person
{
public int No { get; set; }
public string Surname { get; set; }
}
i use the Asynchronous socket Client event to receive message from server.
i receive message from client DataIn(my Event Name) and add to list box ,but not happen to show on UI!
protected void WebSocketClientControl1_OnChatNotification(List < SocketUi > sender) {
ClientScript.RegisterStartupScript(GetType(), "hwa", "javascript:__doPostBack('WebSocketClientControl1','')", true);
}
i cant use the (Response.Redirect & Server.Transfer).
this 2 function have error run time.
i call the javaScript function to show message , not happen on screen.
its my Socket code
public delegate void OnChatNotification(List<SocketUi> sender);
public class WebSocketClientControl : System.Web.UI.Control, IPostBackDataHandler
{
public static ClientService _internalClientService = new ClientService(DServerConfig.ServerAddress.ToString(),
DServerConfig.ServerSoketPort);
public event OnChatNotification OnChatNotification = delegate { };
public WebSocketClientControl()
{
_internalClientService.OnChat += _internalClientService_OnChat;
}
public void Connect(long userID, SocketEnums.EntityType usertype, string username, string key)
{
_internalClientService.Connect(userID, usertype, username, key);
}
private void _internalClientService_OnChat(List<SocketUI.SocketUi> sender)
{
if (OnChatNotification != null)
OnChatNotification(sender);
}
public bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
String presentValue = postDataKey;
String postedValue = postCollection[postDataKey];
if (presentValue == null || !presentValue.Equals(postedValue))
{
return true;
}
return false;
}
public void RaisePostDataChangedEvent()
{
}
}
its my ui Code
private void WebSocketClientControl1_OnChatNotification(List<SocketUI.SocketUi> sender)
{
foreach (SocketUi socketUi in sender)
{
switch (socketUi.DSocketType)
{
case SocketEnums.DSocketType.Chat:
foreach (SocketUI.tb_Chat chatUi in socketUi.Chats)
{
for (int i = 0; i < ASPxPageControl1.TabPages.Count; i++)
{
if (ASPxPageControl1.TabPages[i].Name == "uxTabPage_" + _channels[i].ID.ToString())
{
switch (chatUi.ChatMessegeType)
{
case (int)Enums.ChatMessegeType.Message:
SetNewMessageOnUi(HelperD.UiChat_To_Tb_Chat(chatUi));
break;
case (int)Enums.ChatMessegeType.Readed:
break;
case (int)Enums.ChatMessegeType.OnLinedUser:
break;
case (int)Enums.ChatMessegeType.OffLinedUser:
break;
case (int)Enums.ChatMessegeType.JoinChannle:
case (int)Enums.ChatMessegeType.LeftChannle:
GetUserChannel(chatUi.ChannelID.ID);
break;
case (int)Enums.ChatMessegeType.TypingUser:
for (int j = 0; j < ASPxPageControl1.TabPages[i].Controls.Count; j++)
{
if (ASPxPageControl1.TabPages[i].Controls[j] is System.Web.UI.WebControls.Label &&
ASPxPageControl1.TabPages[i].Controls[j].ID ==
"uxLabel_Status" + ASPxPageControl1.TabPages[i].DataItem.ToString())
{
System.Web.UI.WebControls.Label uxLabel_StatusTemp = new System.Web.UI.WebControls.Label();
uxLabel_StatusTemp = (System.Web.UI.WebControls.Label)ASPxPageControl1.TabPages[i].Controls[j];
uxLabel_StatusTemp.Text = " درحال تایپ " + socketUi.UserName + "...";
// timer1.Start();
}
}
break;
}//End For
// listBox_Message.Items.Add("Me:=>" + chatUi.Message + "\n\r");
}
}
}//End For
break;
}
}
}
private void SetNewMessageOnUi(UiSideLanguage.Database.Chat.tb_Chat item)
{
ASPxTextBox_Message.Text = "";
for (int i = 0; i < ASPxPageControl1.TabPages.Count; i++)
{
for (int j = 0; j < ASPxPageControl1.TabPages[i].Controls.Count; j++)
{
if (ASPxPageControl1.TabPages[i].Controls[j] is System.Web.UI.WebControls.ListBox && ASPxPageControl1.TabPages[i].Controls[j].ID == "uxListView_Chat" + ASPxPageControl1.TabPages[i].DataItem.ToString())
{
System.Web.UI.WebControls.ListBox userListView = (System.Web.UI.WebControls.ListBox)ASPxPageControl1.TabPages[i].Controls[j];
System.Web.UI.WebControls.ListItem listViewItemTemp = new System.Web.UI.WebControls.ListItem();
if (item.AddUser.ID == Language.CacheEntity.CurrentUser.ID)
{
listViewItemTemp.Text = " :من " + item.Message;
// listViewItemTemp.ForeColor = Color.DarkCyan;
}
else
{
listViewItemTemp.Text = item.AddUser.UserName + " : " + item.Message;
// listViewItemTemp.ForeColor = Color.DarkRed;
}
listViewItemTemp.Value = item.MessageFlagID.ToString();
System.Web.UI.WebControls.ListItem isHaveChatItem = null;
foreach (System.Web.UI.WebControls.ListItem chatitemListView in userListView.Items)
{
if (Language.HelperD.GetLong(chatitemListView.Value) == item.MessageFlagID)
{
isHaveChatItem = chatitemListView;
break;
}
}
if (isHaveChatItem != null)
{
if (item.AddUser.ID == Language.CacheEntity.CurrentUser.ID)
{
isHaveChatItem.Text = " :من " + item.Message;
// isHaveChatItem.ForeColor = Color.DarkCyan;
}
else
{
isHaveChatItem.Text = item.ToUser.UserName + " : " + item.Message;
// isHaveChatItem.ForeColor = Color.DarkRed;
}
isHaveChatItem.Value = item.MessageFlagID.ToString();
}
else
{
userListView.Items.Add(listViewItemTemp);
}
}
}
}
}
This function for Update UI >>> SetNewMessageOnUi
I Create Objects on Runtime.
this code is worked
userListView.Items.Add(listViewItemTemp);
and ListView Have Item But On UI Not set.
all objects in the UpdatePanle
It's fairly straight-forward to add a TextField using ABCPDF:
public FormField AddTextField(string inRect, string inName, string inText)
{
int fieldId = mDoc.AddObject("<</Type /Annot /Subtype /Widget /F 4 /FT /Tx /Ff 4096 /Q 1>>");
mDoc.SetInfo(fieldId, "/V:Text", inText);
RegisterField(fieldId, inName, inRect);
return new FormField(fieldId, mDoc);
}
With this as the implementation:
FormField text = AddTextField("40 530 300 580", "TextField1", "Hello World!");
text.DefaultAppearance = "/TimesRoman 36 Tf 0 0 1 rg";
text.BorderColor = "0 0 0";
text.FillColor = "220 220 220";
text.TextAlign = "Left";
If I need to add two fields that have the same name, it's a little more complex:
public int AddGroupField(FormField[] inKids, string inName, string inValue)
{
if (inKids.Length == 0)
throw new Exception("Cannot have a group field with no kids");
string ft = null, dv = null;
int fieldId = mDoc.AddObject("<< /Kids [] >>");
foreach (FormField kid in inKids)
{
mDoc.SetInfo(fieldId, "/Kids[]:Ref", kid.Id.ToString());
mDoc.SetInfo(kid.Id, "/Parent:Ref", fieldId);
if (ft == null)
ft = mDoc.GetInfo(kid.Id, "/FT");
if (dv == null)
dv = mDoc.GetInfo(kid.Id, "/DV");
mDoc.SetInfo(kid.Id, "/FT:Del", "");
mDoc.SetInfo(kid.Id, "/V:Del", "");
mDoc.SetInfo(kid.Id, "/DV:Del", "");
}
mDoc.SetInfo(fieldId, "/FT", ft);
mDoc.SetInfo(fieldId, "/T:Text", inName);
mDoc.SetInfo(fieldId, "/V:Text", inValue);
if (dv != null)
mDoc.SetInfo(fieldId, "/DV:Text", dv);
int eid = mDoc.GetInfoInt(mDoc.Root, "/AcroForm:Ref");
mDoc.SetInfo(eid, "/Fields*[]:Ref", fieldId);
return fieldId;
}
With this as the implementation:
FormField[] kids = new FormField[2];
kids[0] = AddTextField("40 230 300 280", null, null);
kids[1] = AddTextField("40 170 300 220", null, null);
int id = AddGroupField(kids, "TextField1", "Hello World!");
However, I'm having issues with adding a TextField to a PDF where a TextField already exists with that same name. So, for example, if my PDF already has a field named "TextField1" and then I want to add another field with that same name, none of the above implementations will work.
I was able to get the answer from ABCPDF support. And as you can see, it's not exactly a simple process. I'm not sure anyone could just figure this out on their own without spending months and months of research on the PDF spec and the ABCPDF product.
public FormField AddTextField(string inRect, string inName, string inText)
{
bool fieldAlreadyExists = mDoc.Form[inName] != null;
int fieldId = mDoc.AddObject("<</Type /Annot /Subtype /Widget /F 4 /FT /Tx /Ff 4096 /Q 1>>");
mDoc.SetInfo(fieldId, "/V:Text", inText);
RegisterField(fieldId, inName, inRect);
var field = new FormField(fieldId, mDoc);
if (fieldAlreadyExists)
{
InteractiveForm form = new InteractiveForm(mDoc);
form.AddFieldIntoExistingGroup(field, true);
}
return field;
}
private bool AddFieldIntoExistingGroup(FormField field, bool refreshForm)
{
bool duplicatesFound = false;
int acroFormID = mDoc.GetInfoInt(mDoc.Root, "/AcroForm:Ref");
int parentID = mDoc.GetInfoInt(field.Id, "/Parent:Ref");
ArrayAtom kids;
if (parentID > 0)
{
kids = mDoc.ObjectSoup.Catalog.Resolve(Atom.GetItem(mDoc.ObjectSoup[parentID].Atom, "Kids")) as ArrayAtom;
}
else
{
kids = mDoc.ObjectSoup.Catalog.Resolve(Atom.GetItem(mDoc.ObjectSoup[acroFormID].Atom, "Fields")) as ArrayAtom;
}
Dictionary<string, List<IndirectObject>> items = new Dictionary<string, List<IndirectObject>>();
for (int i = 0; i < kids.Count; i++)
{
IndirectObject io = mDoc.ObjectSoup.Catalog.ResolveObj(kids[i]);
if (io == null)
{
continue; // shouldn't really happen
}
string name = mDoc.GetInfo(io.ID, "/T:Text");
if (!items.ContainsKey(name))
{
items[name] = new List<IndirectObject>();
}
items[name].Add(io);
}
foreach (KeyValuePair<string, List<IndirectObject>> pair in items)
{
if (pair.Value.Count > 1)
{
duplicatesFound = true;
// shift field down to be a child of a new field node
int id = mDoc.AddObject("<< >>");
if (parentID > 0)
{
mDoc.SetInfo(parentID, "/Kids[]:Ref", id);
mDoc.SetInfo(id, "/Parent:Ref", parentID);
}
else
{
mDoc.SetInfo(acroFormID, "/Fields[]:Ref", id);
}
string[] dictEntries = new[] { "/FT", "/T", "/TU", "/Ff", "/V", "/DV" };
foreach (IndirectObject io in pair.Value)
{
foreach (string dictEntry in dictEntries)
{
string val = mDoc.GetInfo(io.ID, dictEntry);
if (!string.IsNullOrEmpty(val))
{
mDoc.SetInfo(id, dictEntry, val);
mDoc.SetInfo(io.ID, dictEntry + ":Del", "");
}
}
ArrayRemoveOneRefAtom(kids, io.ID);
mDoc.SetInfo(id, "/Kids[]:Ref", io.ID);
mDoc.SetInfo(io.ID, "/Parent:Ref", id);
}
}
}
if ((refreshForm) && (duplicatesFound))
{
mDoc.Form.Refresh();
}
return duplicatesFound;
}
private static bool ArrayRemoveOneRefAtom(ArrayAtom array, int id)
{
if (array != null)
{
for (int i = 0; i < array.Count; i++)
{
RefAtom refAtom = array[i] as RefAtom;
if ((refAtom != null) && (refAtom.ID == id))
{
ArrayRemoveAt(array, i);
return true;
}
}
}
return false;
}
private static void ArrayRemoveAt(ArrayAtom array, int index)
{
if (index == 0)
{ // Workaround for bug in some versions of ABCpdf
Atom[] copy = new Atom[array.Count];
array.CopyTo(copy, 0);
array.Clear();
for (int i = 1; i < copy.Length; i++)
array.Add(copy[i]);
}
else
{
array.RemoveAt(index);
}
}
What C# template engine
that uses 'pure' HTML having only text and markers
sans any control flow like if, while, loop or expressions,
separating html from control code ?
Below is the example phone book list code,
expressing how this should be done:
string html=#"
<html><head><title>#title</title></head>
<body>
<table>
<tr>
<td> id</td> <td> name</td> <td> sex</td> <td>phones</td>
</tr><!--#contacts:-->
<tr>
<td>#id</td> <td>#name</td> <td>#sex</td>
<td>
<!--#phones:-->#phone <br/>
<!--:#phones-->
</td>
</tr><!--:#contacts-->
</table>
</body>
</html>";
var contacts = from c in db.contacts select c;
Marker m = new Marker(html);
Filler t = m.Mark("title");
t.Set("Phone book");
Filler c = m.Mark("contacts", "id,name,sex");
// **foreach** expressed in code, not in html
foreach(var contact in contacts) {
int id = contact.id;
c.Add(id, contact.name, contact.sex);
Filler p = c.Mark("phones", "phone");
var phones = from ph in db.phones
where ph.id == id
select new {ph.phone};
if (phones.Any()) {
foreach(var ph in phones) {
p.Add(ph);
}
} else {
fp.Clear();
}
}
Console.Out.WriteLine(m.Get());
Use this code:
Templet.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace templaten.com.Templaten
{
public class tRange
{
public int head, toe;
public tRange(int _head, int _toe)
{
head = _head;
toe = _toe;
}
}
public enum AType
{
VALUE = 0,
NAME = 1,
OPEN = 2,
CLOSE = 3,
GROUP = 4
}
public class Atom
{
private AType kin;
private string tag;
private object data;
private List<Atom> bag;
public Atom(string _tag = "",
AType _kin = AType.VALUE,
object _data = null)
{
tag = _tag;
if (String.IsNullOrEmpty(_tag))
_kin = AType.GROUP;
kin = _kin;
if (_kin == AType.GROUP)
bag = new List<Atom>();
else
bag = null;
data = _data;
}
public AType Kin
{
get { return kin; }
}
public string Tag
{
get { return tag; }
set { tag = value; }
}
public List<Atom> Bag
{
get { return bag; }
}
public object Data
{
get { return data; }
set { data = value; }
}
public int Add(string _tag = "",
AType _kin = AType.VALUE,
object _data = null)
{
if (bag != null)
{
bag.Add(new Atom(_tag, _kin, _data));
return bag.Count - 1;
}
else
{
return -1;
}
}
}
public class Templet
{
private string content;
string namepat = "\\w+";
string justName = "(\\w+)";
string namePre = "#";
string namePost = "";
string comment0 = "\\<!--\\s*";
string comment1 = "\\s*--\\>";
private Atom tokens; // parsed contents
private Dictionary<string, int> iNames; // name index
private Dictionary<string, tRange> iGroups; // groups index
private Atom buffer; // output buffer
private Dictionary<string, int> _iname; // output name index
private Dictionary<string, tRange> _igroup; // output index
public Templet(string Content = null)
{
Init(Content);
}
private int[] mark(string[] names, string group)
{
if (names == null || names.Length < 1) return null;
tRange t = new tRange(0, buffer.Bag.Count - 1);
if (group != null)
{
if (!_igroup.ContainsKey(group)) return null;
t = _igroup[group];
}
int[] marks = new int[names.Length];
for (int i = 0; i < marks.Length; i++)
marks[i] = -1;
for (int i = t.head; i <= t.toe; i++)
{
if (buffer.Bag[i].Kin == AType.NAME)
{
for (int j = 0; j < names.Length; j++)
{
if (String.Compare(
names[j],
buffer.Bag[i].Tag,
true) == 0)
{
marks[j] = i;
break;
}
}
}
}
return marks;
}
public Filler Mark(string group, string names)
{
Filler f = new Filler(this, names);
f.di = mark(f.names, group);
f.Group = group;
tRange t = null;
if (_igroup.ContainsKey(group)) t = _igroup[group];
f.Range = t;
return f;
}
public Filler Mark(string names)
{
Filler f = new Filler(this, names);
f.di = mark(f.names, null);
f.Group = "";
f.Range = null;
return f;
}
public void Set(int[] locations, object[] x)
{
int j = Math.Min(x.Length, locations.Length);
for (int i = 0; i < j; i++)
{
int l = locations[i];
if ((l >= 0) && (buffer.Bag[l] != null))
buffer.Bag[l].Data = x[i];
}
}
public void New(string group, int seq = 0)
{
// place new group copied from old group just below it
if (!( iGroups.ContainsKey(group)
&& _igroup.ContainsKey(group)
&& seq > 0)) return;
tRange newT = null;
tRange t = iGroups[group];
int beginRange = _igroup[group].toe + 1;
for (int i = t.head; i <= t.toe; i++)
{
buffer.Bag.Insert(beginRange,
new Atom(tokens.Bag[i].Tag,
tokens.Bag[i].Kin,
tokens.Bag[i].Data));
beginRange++;
}
newT = new tRange(t.toe + 1, t.toe + (t.toe - t.head + 1));
// rename past group
string pastGroup = group + "_" + seq;
t = _igroup[group];
buffer.Bag[t.head].Tag = pastGroup;
buffer.Bag[t.toe].Tag = pastGroup;
_igroup[pastGroup] = t;
// change group indexes
_igroup[group] = newT;
}
public void ReMark(Filler f, string group)
{
if (!_igroup.ContainsKey(group)) return;
Map(buffer, _iname, _igroup);
f.di = mark(f.names, group);
f.Range = _igroup[group];
}
private static void Indexing(string aname,
AType kin,
int i,
Dictionary<string, int> dd,
Dictionary<string, tRange> gg)
{
switch (kin)
{
case AType.NAME: // index all names
dd[aname] = i;
break;
case AType.OPEN: // index all groups
if (!gg.ContainsKey(aname))
gg[aname] = new tRange(i, -1);
else
gg[aname].head = i;
break;
case AType.CLOSE:
if (!gg.ContainsKey(aname))
gg[aname] = new tRange(-1, i);
else
gg[aname].toe = i;
break;
default:
break;
}
}
private static void Map(Atom oo,
Dictionary<string, int> dd,
Dictionary<string, tRange> gg)
{
for (int i = 0; i < oo.Bag.Count; i++)
{
string aname = oo.Bag[i].Tag;
Indexing(oo.Bag[i].Tag, oo.Bag[i].Kin, i, dd, gg);
}
}
public void Init(string Content = null)
{
content = Content;
tokens = new Atom("", AType.GROUP);
iNames = new Dictionary<string, int>();
iGroups = new Dictionary<string, tRange>();
// parse content into tokens
string namePattern = namePre + namepat + namePost;
string patterns =
"(?<var>" + namePattern + ")|" +
"(?<head>" + comment0 + namePattern + ":" + comment1 + ")|" +
"(?<toe>" + comment0 + ":" + namePattern + comment1 + ")";
Regex jn = new Regex(justName, RegexOptions.Compiled);
Regex r = new Regex(patterns, RegexOptions.Compiled);
MatchCollection ms = r.Matches(content);
int pre = 0;
foreach (Match m in ms)
{
tokens.Add(content.Substring(pre, m.Index - pre));
int idx = -1;
if (m.Groups.Count >= 3)
{
string aname = "";
MatchCollection x = jn.Matches(m.Value);
if (x.Count > 0 && x[0].Groups.Count > 1)
aname = x[0].Groups[1].ToString();
AType t = AType.VALUE;
if (m.Groups[1].Length > 0) t = AType.NAME;
if (m.Groups[2].Length > 0) t = AType.OPEN;
if (m.Groups[3].Length > 0) t = AType.CLOSE;
if (aname.Length > 0)
{
tokens.Add(aname, t);
idx = tokens.Bag.Count - 1;
}
Indexing(aname, t, idx, iNames, iGroups);
}
pre = m.Index + m.Length;
}
if (pre < content.Length)
tokens.Add(content.Substring(pre, content.Length - pre));
// copy tokens into buffer
buffer = new Atom("", AType.GROUP);
for (int i = 0; i < tokens.Bag.Count; i++)
buffer.Add(tokens.Bag[i].Tag, tokens.Bag[i].Kin);
// initialize index of output names
_iname = new Dictionary<string, int>();
foreach (string k in iNames.Keys)
_iname[k] = iNames[k];
// initialize index of output groups
_igroup = new Dictionary<string, tRange>();
foreach (string k in iGroups.Keys)
{
tRange t = iGroups[k];
_igroup[k] = new tRange(t.head, t.toe);
}
}
public string Get()
{
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < buffer.Bag.Count; i++)
{
switch (buffer.Bag[i].Kin)
{
case AType.VALUE:
sb.Append(buffer.Bag[i].Tag);
break;
case AType.NAME:
sb.Append(buffer.Bag[i].Data);
break;
case AType.OPEN:
case AType.CLOSE:
break;
default: break;
}
}
return sb.ToString();
}
}
public class Filler
{
private Templet t = null;
public int[] di;
public string[] names;
public string Group { get; set; }
public tRange Range { get; set; }
private int seq = 0;
public Filler(Templet tl, string markers = null)
{
t = tl;
if (markers != null)
names = markers.Split(new char[] { ',' },
StringSplitOptions.RemoveEmptyEntries);
else
names = null;
}
public void init(int length)
{
di = new int[length];
for (int i = 0; i < length; i++)
di[i] = -1;
seq = 0;
Group = "";
Range = null;
}
// clear contents inside marked object or group
public void Clear()
{
object[] x = new object[di.Length];
for (int i = 0; i < di.Length; i++)
x[i] = null;
t.Set(di, x);
}
// set value for marked object,
// or add row to group and set value to columns
public void Set(params object[] x)
{
t.Set(di, x);
}
public void Add(params object[] x)
{
if (Group.Length > 0)
{
t.New(Group, seq);
++seq;
t.ReMark(this, Group);
}
t.Set(di, x);
}
}
}
Testing program
Program.cs
Templet m = new Templet(html);
Filler f= m.Mark("title");
f.Set("Phone book");
Filler fcontacts = m.Mark("contacts", "id,name,sex,phone");
fcontacts.Add(1, "Akhmad", "M", "123456");
fcontacts.Add(2, "Barry", "M", "234567");
fcontacts.Add(1, "Charles", "M", "345678");
Console.Out.WriteLine(m.Get());
Still can't do nested loop- yet.
Just use ASP.NET. Whether you use webforms or MVC, it's super easy to have C# in your .cs files, and HTML in your .aspx files.
As with anything in programming, it's 99% up to you to do things right. Flexible UI engines aren't going to enforce that you follow good coding practices.
In principle most any template engine you choose can separate HTML from control logic with the proper architecture. using an MVC (Or MVVM) pattern, if you construct your model in such a way that the controller contains the if/then logic instead of the view you can eliminate it from the view.
That said, the syntax you use is very close to Razor syntax which is easily available for ASP.NET MVC through NuGet packages.
I totally hear you. I built SharpFusion, which has some other stuff in it but if you look for the template.cs file you will see the handler that parses a HTML file and simply replaces out tokens with values that you've made in c#.
Because no XML parsing is done like ASP.NET the framework loads much faster than even an MVC site.
Another alternative is ServiceStack.