Attribute alignment after edit in AutoCAD - autocad

I have a simple routine that updates the text value of an attributereference. After the routine runs the values are updated in the drawing but the text is left justified and not centered. I have not been able to find any command that will cause AutoCAD to update the text location. So any help would be appreciated.
My Code
using (Transaction acTrans = db.TransactionManager.StartTransaction())
{
BlockTable bt = (BlockTable)acTrans.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId oid in bt)
{
BlockTableRecord btr = (BlockTableRecord)acTrans.GetObject(oid, OpenMode.ForRead);
foreach (ObjectId o in btr)
{
if (o.ObjectClass.Name == "AcDbBlockReference")
{
BlockReference br = (BlockReference)acTrans.GetObject(o, OpenMode.ForRead);
BlockTableRecord b2 = (BlockTableRecord)acTrans.GetObject(br.BlockTableRecord, OpenMode.ForRead);
if (b2.Name == blockName)
{
AttributeCollection ac = br.AttributeCollection;
foreach (ObjectId i in ac)
{
AttributeReference ar = (AttributeReference)acTrans.GetObject(i, OpenMode.ForWrite);
string tagName = ar.Tag;
foreach (TestAutoCADCntrl.CBAttributeTag t in tags)
{
if (t.TagName == tagName)
{
ar.Justify = AttachmentPoint.MiddleCenter;
ar.AdjustAlignment(db);
ar.TextString = t.TagValue;
ar.DowngradeOpen();
}
}
}
br.RecordGraphicsModified(true);
}
}
}
}
acTrans.Commit();

Sorry, I have been searching for this issue for 3 days and found the answer right after i posted this question. For anyone else you just need to change the working database before you update the attribute text value.
foreach (TestAutoCADCntrl.CBAttributeTag t in tags)
{
if (t.TagName == tagName)
{
Database wdb = HostApplicationServices.WorkingDatabase; HostApplicationServices.WorkingDatabase = db;
ar.TextString = t.TagValue;
ar.AdjustAlignment(db);
HostApplicationServices.WorkingDatabase = wdb;
}
}

Related

copy one or more selected row from Janus Grid to DataRowCollection or DataRow[]

I have a Janus Grid with a checkbox in each row and wanna copy selected row(s) to a DataRowCollection or to DataRow[] .this is my way but not completed and not worked:
also this grid has group on one field and I use 2 loop for group and childs.
gridEX1.DataSource = dtALL;//dtALL is a data table fill with select sql command
DataRowCollection dr
DataRow dr2=dtALL.NewRow();
foreach (Janus.Windows.GridEX.GridEXRow g in gridEX1.GetRows())
{
foreach (Janus.Windows.GridEX.GridEXRow r in g.GetChildRows())
{
if ((bool)r.Cells["sendALL"].Value == true && r.Cells["DocTitle"].Value.ToString() == DocTitle)
{
for(int i=0;i<r.Cells.Count;i++)
if(r.Cells[i].GetType()==typeof(TextBox))
{
dr2[i] = r.Cells[i].Value;
}
dr.Add(dr2);
}
}
}
I figured out this way and solved my problem:
DataTable dt1copy = new DataTable();
dt1copy.Columns.Add("DocTitle");
dt1copy.Columns.Add("DocDetails");
dt1copy.Columns.Add("ExpLenght");
dt1copy.Columns.Add("ReqDate");
dt1copy.Columns.Add("ReqTypeDetailsTitle");
dt1copy.Columns.Add("ReqTypeTitle");
dt1copy.Columns.Add("UnitsTitle");
dt1copy.Columns.Add("DocType");
dt1copy.Columns.Add("DocSuffix");
dt1copy.Columns.Add("FKGID");
dt1copy.Columns.Add("Id");//id of docinreq tbl
DataRow dr2;
DataRowCollection dr = dt1copy.Rows;
string DocTitle = gridEX1.CurrentRow.Cells["DocTitle"].Value.ToString();
foreach (Janus.Windows.GridEX.GridEXRow g in gridEX1.GetRows())
{
foreach (Janus.Windows.GridEX.GridEXRow r in g.GetChildRows())
{
try
{
if ((bool)r.Cells["sendALL"].Value == true && r.Cells["DocTitle"].Value.ToString() == DocTitle)
{
dr2 = dt1copy.NewRow();
for (int i = 0, j = 0; i < r.Cells.Count; i++)
{
if (r.Cells[i].Column.BoundMode != Janus.Windows.GridEX.ColumnBoundMode.UnboundFetch)//select only bounded column from grid
{
dr2[j] = r.Cells[i].Value.ToString();
j++;
}
}
dt1copy.Rows.Add(dr2);
}
}
catch (Exception) { }
}
}
dr = dt1copy.Rows;

How can improve this Linq query expressions performance?

public bool SaveValidTicketNos(string id,string[] ticketNos, string checkType, string checkMan)
{
bool result = false;
List<Carstartlistticket>enties=new List<Carstartlistticket>();
using (var context = new MiniSysDataContext())
{
try
{
foreach (var ticketNo in ticketNos)
{
Orderticket temp = context.Orderticket.ByTicketNo(ticketNo).SingleOrDefault();
if (temp != null)
{
Ticketline ticketline= temp.Ticketline;
string currencyType = temp.CurrencyType;
float personAllowance=GetPersonCountAllowance(context,ticketline, currencyType);
Carstartlistticket carstartlistticket = new Carstartlistticket()
{
CsltId = Guid.NewGuid().ToString(),
Carstartlist = new Carstartlist(){CslId = id},
LeaveDate = temp.LeaveDate,
OnPointName = temp.OnpointName,
OffPointName = temp.OffpointName,
OutTicketMan = temp.OutBy,
TicketNo = temp.TicketNo,
ChekMan = checkMan,
Type = string.IsNullOrEmpty(checkType)?(short?)null:Convert.ToInt16(checkType),
CreatedOn = DateTime.Now,
CreatedBy = checkMan,
NumbserAllowance = personAllowance
};
enties.Add(carstartlistticket);
}
}
context.BeginTransaction();
context.Carstartlistticket.InsertAllOnSubmit(enties);
context.SubmitChanges();
bool changeStateResult=ChangeTicketState(context, ticketNos,checkMan);
if(changeStateResult)
{
context.CommitTransaction();
result = true;
}
else
{
context.RollbackTransaction();
}
}
catch (Exception e)
{
LogHelper.WriteLog(string.Format("CarstartlistService.SaveValidTicketNos({0},{1},{2},{3})",id,ticketNos,checkType,checkMan),e);
context.RollbackTransaction();
}
}
return result;
}
My code is above. I doubt these code have terrible poor performance. The poor performance in the point
Orderticket temp = context.Orderticket.ByTicketNo(ticketNo).SingleOrDefault();
,actually, I got an string array through the method args,then I want to get all data by ticketNos from database, here i use a loop,I know if i write my code like that ,there will be cause performance problem and it will lead one more time database access,how can avoid this problem and improve the code performance,for example ,geting all data by only on databse access
I forget to tell you the ORM I use ,en ,the ORM is PlinqO based NHibernate
i am looking forward to having your every answer,thank you
using plain NHibernate
var tickets = session.QueryOver<OrderTicket>()
.WhereRestrictionOn(x => x.TicketNo).IsIn(ticketNos)
.List();
short? type = null;
short typeValue;
if (!string.IsNullOrEmpty(checkType) && short.TryParse(checkType, out typeValue))
type = typeValue;
var entitiesToSave = tickets.Select(ticket => new Carstartlistticket
{
CsltId = Guid.NewGuid().ToString(),
Carstartlist = new Carstartlist() { CslId = id },
LeaveDate = ticket.LeaveDate,
OnPointName = ticket.OnpointName,
OffPointName = ticket.OffpointName,
OutTicketMan = ticket.OutBy,
TicketNo = ticket.TicketNo,
ChekMan = checkMan,
CreatedOn = DateTime.Now,
CreatedBy = checkMan,
Type = type,
NumbserAllowance = GetPersonCountAllowance(context, ticket.Ticketline, ticket.CurrencyType)
});
foreach (var entity in entitiesToSave)
{
session.Save(entity);
}
to enhance this further try to preload all needed PersonCountAllowances

DataTable that has List<string> in it

I'm using Linq to return data from an XML file to a DataTable and that works. But now I'm trying to modify the code to loop through the DataTable. I created a custom class to model the data and have a List in my model. When I loop through the DataTable to display records it displays System.Collections.Generic.List`1[System.String] instead of the actual data. I'm not sure what to search to find the answer.
Snippet:
foreach (DataRow row in tbl.Rows)
{
myList = row["myList"] + ", " + myList;
}
The myList column is the List. I hope this makes sense.
Edited:
public static DataTable LINQToDataTable<T>(IEnumerable<T> varlist)
{
DataTable dtReturn = new DataTable();
// column names
PropertyInfo[] oProps = null;
if (varlist == null) return dtReturn;
foreach (T rec in varlist)
{
// Use reflection to get property names, to create table, Only first time, others will follow
if (oProps == null)
{
oProps = ((Type)rec.GetType()).GetProperties();
foreach (PropertyInfo pi in oProps)
{
Type colType = pi.PropertyType;
if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
{
colType = colType.GetGenericArguments()[0];
}
dtReturn.Columns.Add(new DataColumn(pi.Name, colType));
}
}
DataRow dr = dtReturn.NewRow();
foreach (PropertyInfo pi in oProps)
{
dr[pi.Name] = pi.GetValue(rec, null) == null ?DBNull.Value :pi.GetValue
(rec,null);
}
dtReturn.Rows.Add(dr);
}
return dtReturn;
}
hobbiesList = (List<string>)row["hobbies"];
foreach (var item in hobbiesList)
{
hobbies.Add(item.ToString());
}
hobby = string.Join(", ", hobbies.ToArray());
hobbies.Clear();
I had to do the above to get it to work. I then add hobby to my output array.

System.IndexOutOfRangeException: Cannot find column

I am implementing gridview sorting which is part of a user control. Below code gives me Indexoutofrange error.
The error message is at
dtView.Sort = strSort;
Errormessage:
System.IndexOutOfRangeException: Cannot find column TEXT_COUNTY_ID.
Can anyone point out what I am doing wrong?
protected void SortGridData_Hkl(Object sender, GridViewSortEventArgs e)
{
GridView _dgd_work_onoff = (GridView)Page.FindControl("bodyuc$dgd_work_onoff");
DataSet dstemp;
DataView dtView;
if (ViewState["dsfetchResults"] != null)
{
dstemp = (DataSet)ViewState["dsfetchResults"];
string strSortOrder = ViewState["SortOrder"].ToString();
if (strSortOrder == "DESC")
{
strSortOrder = "ASC";
ViewState["SortOrder"] = strSortOrder;
}
else
{
strSortOrder = "DESC";
ViewState["SortOrder"] = strSortOrder;
}
string strSort = e.SortExpression.ToString() + " " + strSortOrder;
ViewState["SortString"] = strSort;
dtView = dstemp.Tables[0].DefaultView;
dtView.Sort = strSort;
if (dtView.Count != 0)
{
if (_dgd_work_onoff != null)
{
_dgd_work_onoff.DataSource = dtView;
_dgd_work_onoff.DataBind();
}
}
}
'dsfetchResults' is suppose to contain the data from the database.
Got the solution. The column name was different from that of the database column.

save new or update exist record with linq

this is the way i used to save record with linq: (my Q is below)
public void SaveEmployee(Employee employee)
{
using (BizNetDB db = new BizNetDB())
{
BizNet.SqlRep.Data.Employee oldEmployee = (from e in db.Employees
where e.EmployeeID == employee.EmployeeID
select e).SingleOrDefault();
if (oldEmployee == null)
{
oldEmployee = new BizNet.SqlRep.Data.Employee();
oldEmployee.BirthDate = employee.BirthDate;
oldEmployee.WorkRole = employee.WorkRole;
oldEmployee.CurrentFlag = employee.CurrentFlag;
oldEmployee.HireDate = employee.HireDate;
...
db.Employees.InsertOnSubmit(oldEmployee);
}
else
{
if (oldEmployee.BirthDate.Date != employee.BirthDate.Date)
oldEmployee.BirthDate = employee.BirthDate;
if (oldEmployee.CurrentFlag != employee.CurrentFlag)
oldEmployee.CurrentFlag = employee.CurrentFlag;
if (oldEmployee.HireDate.Date != employee.HireDate.Date)
oldEmployee.HireDate = employee.HireDate;
}
oldEmployee.ModifiedDate = DateTime.Now;
db.SubmitChanges();
employee.EmployeeID = oldEmployee.EmployeeID;
}
}
my questions are:
a. are the if statements nesccery? why not to make the assigning without the
check?
mybe the if block take more cpu..
b. why to spearate the new record block and the update block?
when the record is new it will do
db.Employees.InsertOnSubmit(oldEmployee);
and then proceed with the update routine...
The way you're doing it the only reason you need the if statement is to new it up and insert it, so I would use the if statement just for that.
I would do this instead:
public void SaveEmployee(Employee employee)
{
using (BizNetDB db = new BizNetDB())
{
BizNet.SqlRep.Data.Employee oldEmployee =
(from e in db.Employees
where e.EmployeeID == employee.EmployeeID
select e).SingleOrDefault();
if (oldEmployee == null)
{
oldEmployee = new BizNet.SqlRep.Data.Employee();
db.Employees.InsertOnSubmit(oldEmployee);
}
if (oldEmployee.BirthDate.Date != employee.BirthDate.Date)
oldEmployee.BirthDate = employee.BirthDate;
if (oldEmployee.CurrentFlag != employee.CurrentFlag)
oldEmployee.CurrentFlag = employee.CurrentFlag;
if (oldEmployee.HireDate.Date != employee.HireDate.Date)
oldEmployee.HireDate = employee.HireDate;
oldEmployee.ModifiedDate = DateTime.Now;
db.SubmitChanges();
employee.EmployeeID = oldEmployee.EmployeeID;
}
}
I also think there's a way to map one object's properties to the other, but it escapes me at the moment. It may not work for what you're trying to do anyway since it seems that you're doing some other things later anyway with the ModifiedDate and EmployeeID.

Resources