NET start > .NET newbies
Links to web ressources
Patriiick:
A C# version would be welcome.
(gile):
Hi
Stephen Preston may add C# versions (see here).
Waiting this, I purpose my conversion of the provided samples.
The two main differences between VB and C# are syntax and strictness (while VB option 'strict' is off which is the default).
C# is more strongly typed and allows less implicit casts.
KeepAttributesHorizontal - Lesson 1 Completed
Only syntax differences with the VB code.
Prefixing the class fields with an underscore is not requiered (it's only a convention as using 'my*' in VB languages).
--- Code: ---using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
namespace KeepAttributesHorizontalCs
{
public class Commands
{
private static KeepStraightOverrule _overrule;
[CommandMethod("KeepStraight")]
public static void ImplementOverrule()
{
// We only want to create our overrule instance once,
// so we check if it already exists before we create it
// (i.e. this may be the 2nd time we've run the command)
if (_overrule == null)
{
// Instantiate our overrule class
_overrule = new KeepStraightOverrule();
// Register the overrule
Overrule.AddOverrule
(RXClass.GetClass(typeof(AttributeReference)),
_overrule, false);
}
// Make sure overruling is turned on so our overrule works
Overrule.Overruling = true;
}
}
// Our custom overrule class derived from TransformOverrule
public class KeepStraightOverrule : TransformOverrule
{
// We want to change how an AttributeReference responds to being
// transformed (moved, rotated, etc.), so we override its
// standard TransformBy function.
public override void TransformBy(Entity entity, Matrix3d transform)
{
// Call the normal TransformBy function for the attribute
// reference we're overruling.
base.TransformBy(entity, transform);
// We know entity must be an AttributeReference because
// that is the only entity we registered the overrule for.
AttributeReference attRef = (AttributeReference)entity;
// Set rotation of attribute reference to 0 (horizontal)
attRef.Rotation = 0.0;
}
}
}
--- End code ---
ObjectOrientedSample
--- Code: ---using Autodesk.AutoCAD.Runtime;
namespace ObjectOrientedSampleCs
{
public class Commands
{
[CommandMethod("RunTest")]
public void Test()
{
Point pt1 = new Point();
// Use Step Into on the next line to step into SetLocation
pt1.SetLocation(10, 10);
int xVal1 = pt1.X;
pt1.X = 9;
int xVal2 = pt1.X;
NewPoint pt2 = new NewPoint();
pt2.SetLocation(20, 20);
int xVal3 = pt2.X;
pt2.X = 9;
// Z is new to the NewPoint class
pt2.Z = 12;
Point pt3 = pt2;
// pt3 is variable of type Point, but holds an object of type NewPoint
}
}
public class Point
{
private int _xCoord;
private int _yCoord;
public void SetLocation(int x, int y)
{
_xCoord = x;
_yCoord = y;
}
public int X
{
get { return _xCoord; }
set { _xCoord = value; }
}
public int Y
{
get { return _yCoord; }
set { _yCoord = value; }
}
}
public class NewPoint : Point
{
private int _zCoord;
public int Z
{
get { return _zCoord; }
set
{
// Don't accept negative Z values
if (value >= 0)
{
_zCoord = value;
}
}
}
}
}
--- End code ---
KeepAttributesHorizontal - Lesson 5 Completed
Strictness difference:
VB = implicit cast from Entity to AttributeReference:
Dim attRef As AttributeReference = entity
C# = explicit cast from Entity to AttributeReference
AttributeReference attRef = (AttributeReference)entity;
Array size initialisation difference:
VB = upper bound
ReDim objIds(attRefColl.Count)
attRefColl.CopyTo(objIds, 0)
ReDim Preserve objIds(attRefColl.Count - 1)
C# = number of items
ObjectId[] objIds = new ObjectId[attRefColl.Count + 1];
attRefColl.CopyTo(objIds, 0);
System.Array.Resize(ref objIds, attRefColl.Count);
--- Code: ---Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput
Namespace HorizontalAttributes
Public Class Commands
' Class variable to store the instance of our overrule
Private Shared myOverrule As KeepStraightOverrule
<CommandMethod("KeepStraight")>
Public Shared Sub ImplementOverrule()
Dim doc As Document =
Application.DocumentManager.MdiActiveDocument
Dim ed As Editor = doc.Editor
' Select a block reference
Dim opts As New PromptEntityOptions(
vbLf & "Select a block reference:")
opts.SetRejectMessage(vbLf & "Must be block reference...")
opts.AddAllowedClass(GetType(BlockReference), True)
Dim res As PromptEntityResult = ed.GetEntity(opts)
If res.Status <> PromptStatus.OK Then
Exit Sub
End If
Dim objIds() As ObjectId
Dim db As Database = doc.Database
Using trans As Transaction =
db.TransactionManager.StartTransaction
' Open the BlockReference for read.
' We know its a BlockReference because we set a filter in
' our PromptEntityOptions
Dim blkRef As BlockReference =
trans.GetObject(res.ObjectId, OpenMode.ForRead)
' Record the ObjectIds of all AttributeReferences
' attached to the BlockReference.
Dim attRefColl As AttributeCollection =
blkRef.AttributeCollection
ReDim objIds(attRefColl.Count)
attRefColl.CopyTo(objIds, 0)
ReDim Preserve objIds(attRefColl.Count - 1)
End Using
'We only want to create our overrule instance once,
' so we check if it already exists before we create it
' (i.e. this may be the 2nd time we've run the command)
If myOverrule Is Nothing Then
'Instantiate our overrule class
myOverrule = New KeepStraightOverrule
'Register the overrule
Overrule.AddOverrule(
RXClass.GetClass(GetType(AttributeReference)),
myOverrule, False)
End If
'Specify which Attributes will be overruled
myOverrule.SetIdFilter(objIds)
'Make sure overruling is turned on so our overrule works
Overrule.Overruling = True
End Sub
End Class
'Our custom overrule class derived from TransformOverrule
Public Class KeepStraightOverrule
Inherits TransformOverrule
'We want to change how an AttributeReference responds to being
' transformed (moved, rotated, etc.), so we override its
' standard TransformBy function.
Public Overrides Sub TransformBy(ByVal entity As Entity,
ByVal transform As Matrix3d)
'Call the normal TransformBy function for the attribute
' reference we're overruling.
MyBase.TransformBy(entity, transform)
'We know entity must be an AttributeReference because
' that is the only entity we registered the overrule for.
Dim attRef As AttributeReference = entity
'Set rotation of attribute reference to 0 (horizontal)
attRef.Rotation = 0.0
End Sub
End Class
End Namespace
--- End code ---
KeepAttributesHorizontal - Lesson 6 Completed
--- Code: ---using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
namespace KeepAttributesHorizontalCs
{
public class Commands
{
// Class variable to store the instance of our overrule
private static KeepStraightOverrule _overrule;
// Registered Application Id for Xdata
private const string _regAppName = "ADSK_ATTRIBUTE_ZERO_OVERRULE";
[CommandMethod("KeepStraight")]
public static void ImplementOverrule()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
// Select a block reference
PromptEntityOptions opts = new PromptEntityOptions("\nSelect a block reference: ");
opts.SetRejectMessage("\nMust be block reference...");
opts.AddAllowedClass(typeof(BlockReference), true);
PromptEntityResult res = ed.GetEntity(opts);
if (res.Status != PromptStatus.OK)
return;
Database db = doc.Database;
AddRegAppId(db);
using (Transaction trans = db.TransactionManager.StartTransaction())
{
// Open the BlockReference for read.
// We know its a BlockReference because we set a filter in
// our PromptEntityOptions.
BlockReference blkRef =
(BlockReference)trans.GetObject(res.ObjectId, OpenMode.ForRead);
// Record the ObjectIds of all AttributeReferences
// attached to the BlockReference.
AttributeCollection attRefColl = blkRef.AttributeCollection;
// Iterate through ObjectIds of all AttributeReferences
// attached to the BlockReference, opening each
// AttributeReference and adding xdata to it.
foreach (ObjectId objId in attRefColl)
{
AttributeReference attRef =
(AttributeReference)trans.GetObject(objId, OpenMode.ForWrite);
// Create new xdata containing the overrule filter name
using (ResultBuffer resBuf = new ResultBuffer(
new TypedValue((int)DxfCode.ExtendedDataRegAppName, _regAppName),
new TypedValue((int)DxfCode.ExtendedDataAsciiString, "Dummy text")))
{
// Add the xdata
attRef.XData = resBuf;
}
}
trans.Commit();
}
// Create and register our overrule and turn overruling on.
ActivateOverrule();
}
[CommandMethod("DontKeepStraight")]
public static void RemoveXdata()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
// Select a block reference
PromptEntityOptions opts = new PromptEntityOptions("\nSelect a block reference: ");
opts.SetRejectMessage("\nMust be block reference...");
opts.AddAllowedClass(typeof(BlockReference), true);
PromptEntityResult res = ed.GetEntity(opts);
if (res.Status != PromptStatus.OK)
return;
Database db = doc.Database;
AddRegAppId(db);
using (Transaction trans = db.TransactionManager.StartTransaction())
{
// Open the BlockReference for read.
// We know its a BlockReference because we set a filter in
// our PromptEntityOptions.
BlockReference blkRef =
(BlockReference)trans.GetObject(res.ObjectId, OpenMode.ForRead);
// Record the ObjectIds of all AttributeReferences
// attached to the BlockReference.
AttributeCollection attRefColl = blkRef.AttributeCollection;
// Iterate through ObjectIds of all AttributeReferences
// attached to the BlockReference, opening each
// AttributeReference and adding xdata to it.
foreach (ObjectId objId in attRefColl)
{
AttributeReference attRef =
(AttributeReference)trans.GetObject(objId, OpenMode.ForWrite);
// Create new xdata containing the overrule filter name
using (ResultBuffer resBuf = new ResultBuffer(
new TypedValue((int)DxfCode.ExtendedDataRegAppName, _regAppName)))
{
// Add the xdata
// Because we leave this blank except for the regappid,
// it erases any Xdata we previously added.
attRef.XData = resBuf;
}
}
trans.Commit();
}
}
[CommandMethod("ActivateOverrule")]
private static void ActivateOverrule()
{
// We only want to create our overrule instance once,
// so we check if it already exists before we create it
// (i.e. this may be the 2nd time we've run the command)
if (_overrule == null)
{
// Instantiate our overrule class
_overrule = new KeepStraightOverrule();
// Register the overrule
Overrule.AddOverrule
(RXClass.GetClass(typeof(AttributeReference)),
_overrule, false);
}
// Specify which Attributes will be overruled
_overrule.SetXDataFilter(_regAppName);
// Make sure overruling is turned on so our overrule works
Overrule.Overruling = true;
}
private static void AddRegAppId(Database db)
{
using (Transaction trans = db.TransactionManager.StartTransaction())
{
// First create our RegAppId (if it doesn't already exist)
RegAppTable appTbl =
(RegAppTable)trans.GetObject(db.RegAppTableId, OpenMode.ForRead);
if (!appTbl.Has(_regAppName))
{
RegAppTableRecord appTblRec = new RegAppTableRecord();
appTblRec.Name = _regAppName;
appTbl.UpgradeOpen();
appTbl.Add(appTblRec);
trans.AddNewlyCreatedDBObject(appTblRec, true);
}
trans.Commit();
}
}
}
// Our custom overrule class derived from TransformOverrule
public class KeepStraightOverrule : TransformOverrule
{
// We want to change how an AttributeReference responds to being
// transformed (moved, rotated, etc.), so we override its
// standard TransformBy function.
public override void TransformBy(Entity entity, Matrix3d transform)
{
// Call the normal TransformBy function for the attribute
// reference we're overruling.
base.TransformBy(entity, transform);
// We know entity must be an AttributeReference because
// that is the only entity we registered the overrule for.
AttributeReference attRef = (AttributeReference)entity;
// Set rotation of attribute reference to 0 (horizontal)
attRef.Rotation = 0.0;
}
}
}
--- End code ---
(gile):
Bonus Plugin
Refactorised code
Edit: the the matrix calculation in the BillboardAttributesOverrule.ViewportDraw() method have been re-written so that it works whatever the block insertion plane.
Edit 2: corrected code so that it works whatever the attribute text justificaion.
--- Code: ---using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
namespace BonusPluginCs
{
//public class ExtensionApplication : IExtensionApplication
//{
// public void Initialize()
// {
// Commands.ActivateOverrule();
// }
// public void Terminate() { }
//}
public class Commands
{
private static BillboardAttributesOverrule _overrule;
// Registered Application Id for Xdata
private const string regAppName = "ADSK_ATTRIBUTE_ZERO_OVERRULE";
[CommandMethod("BillboardAttributes")]
public static void ImplementOverrule()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
// Select a block reference
PromptEntityResult res = GetBlkRef(ed);
if (res.Status != PromptStatus.OK)
return;
// Create and register our overrule and turn overruling on.
ActivateOverrule();
// Create new xdata containing the overrule filter name
using (ResultBuffer resBuf = new ResultBuffer(
new TypedValue((int)DxfCode.ExtendedDataRegAppName, regAppName),
new TypedValue((int)DxfCode.ExtendedDataAsciiString, "Dummy text")))
{
// Add the xdata
AddXdata(res.ObjectId, resBuf, db);
}
}
[CommandMethod("DontBillboardAttributes")]
public static void RemoveXdata()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
// Select a block reference
PromptEntityResult res = GetBlkRef(ed);
if (res.Status != PromptStatus.OK)
return;
// Create new xdata containing the overrule filter name
using (ResultBuffer resBuf = new ResultBuffer(
new TypedValue((int)DxfCode.ExtendedDataRegAppName, regAppName)))
{
// Add the xdata
// Because we leave this blank except for the regappid,
// it erases any Xdata we previously added.
AddXdata(res.ObjectId, resBuf, db);
}
}
[CommandMethod("ActivateBillboardOverrule")]
public static void ActivateOverrule()
{
// We only want to create our overrule instance once,
// so we check if it already exists before we create it
// (i.e. this may be the 2nd time we've run the command)
if (_overrule == null)
{
// Instantiate our overrule class
_overrule = new BillboardAttributesOverrule();
// Register the overrule
Overrule.AddOverrule
(RXClass.GetClass(typeof(AttributeReference)),
_overrule, false);
}
// Specify which Attributes will be overruled
_overrule.SetXDataFilter(regAppName);
// Make sure overruling is turned on so our overrule works
Overrule.Overruling = true;
}
private static PromptEntityResult GetBlkRef(Editor ed)
{
PromptEntityOptions opts = new PromptEntityOptions("\nSelect a block reference: ");
opts.SetRejectMessage("\nMust be block reference...");
opts.AddAllowedClass(typeof(BlockReference), true);
return ed.GetEntity(opts);
}
private static void AddXdata(ObjectId id, ResultBuffer resBuf, Database db)
{
using (Transaction trans = db.TransactionManager.StartTransaction())
{
// First create our RegAppId (if it doesn't already exist)
RegAppTable appTbl =
(RegAppTable)trans.GetObject(db.RegAppTableId, OpenMode.ForRead);
if (!appTbl.Has(regAppName))
{
RegAppTableRecord appTblRec = new RegAppTableRecord();
appTblRec.Name = regAppName;
appTbl.UpgradeOpen();
appTbl.Add(appTblRec);
trans.AddNewlyCreatedDBObject(appTblRec, true);
}
// Open the BlockReference for read.
// We know its a BlockReference because we set a filter in
// our PromptEntityOptions.
BlockReference blkRef =
(BlockReference)trans.GetObject(id, OpenMode.ForRead);
// Record the ObjectIds of all AttributeReferences
// attached to the BlockReference.
AttributeCollection attRefColl = blkRef.AttributeCollection;
// Iterate through ObjectIds of all AttributeReferences
// attached to the BlockReference, opening each
// AttributeReference and adding xdata to it.
foreach (ObjectId objId in attRefColl)
{
AttributeReference attRef =
(AttributeReference)trans.GetObject(objId, OpenMode.ForWrite);
// Add the xdata
attRef.XData = resBuf;
}
trans.Commit();
}
}
}
// Our custom overrule class derived from TransformOverrule
public class BillboardAttributesOverrule : DrawableOverrule
{
// Returning False from WorldDraw tells AutoCAD this entity has
// viewport dependent graphics.
public override bool WorldDraw(Drawable drawable, WorldDraw wd)
{
return false;
}
// Called for each viewport so entity can draw itself differently
// depending on the view.
public override void ViewportDraw(Drawable drawable, ViewportDraw vd)
{
// Cast drawable to type AttributeReference (we know it's an
// AttributeReference because that's the only class we register our
// overrule for).
AttributeReference attRef = (AttributeReference)drawable;
// First calculate the transformation matrix to rotate from the
// BlockReference's current orientation to the view.
Point3d org = attRef.Justify == AttachmentPoint.BaseLeft ||
attRef.Justify == AttachmentPoint.BaseAlign ||
attRef.Justify == AttachmentPoint.BaseFit ?
attRef.Position : attRef.AlignmentPoint;
Matrix3d viewMat =
Matrix3d.PlaneToWorld(new Plane(org, vd.Viewport.ViewDirection)) *
Matrix3d.WorldToPlane(new Plane(org, attRef.Normal)) *
Matrix3d.Rotation(-attRef.Rotation, attRef.Normal, org);
// Apply the transformation
vd.Geometry.PushModelTransform(viewMat);
// Draw the 'per viewport geometry
base.ViewportDraw(drawable, vd);
// Remove the transformation - we don't want any other objects
// to draw themselves in the view plane.
vd.Geometry.PopModelTransform();
}
// This function tells AutoCAD to dynamically update the
// AttributeReference during view transitions (e.g. 3DORBIT).
// Comment it out to improve graphic update performance.
public override int SetAttributes(Drawable drawable, DrawableTraits traits)
{
return base.SetAttributes(drawable, traits) | (int)DrawableAttributes.ViewDependentViewportDraw;
}
}
}
--- End code ---
Patriiick:
Thanks Gille, did you used an automatic conversion tool?
(gile):
--- Quote from: Patriiick on January 01, 2012, 06:28:49 PM ---Thanks Gille, did you used an automatic conversion tool?
--- End quote ---
No, not this time.
With automatic conversion tools, there're often issues from VB to C# when the VB code wasn't written with 'option strict'.
Doing these conversion was a nice way to learn a little about Overrules.
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version