Debugger shows not existing properties of an object - visual-studio

I am using Svg .Net lib. Here is my method code
public void X()
{
Svg.SvgDocument svgDocument = SvgDocument.Open(Path);
foreach (var child in svgDocument.Children)
{
foreach (var step in child.Children)
{
if (step.ID.StartsWith("node"))
{
var el = step.Children[2];
var id = el.Content;
}
}
}
}
And here is what I can see in a debugger:
My question is how I can see Bounds property if object does not have it?
Thanks!

The debugger always shows the properties of the actual (dynamic) instance of the object, not the static type of the variable you're referring to. It tries to give you as much information about the object as possible. If you check the third column in the watch window, it tells you the static type of the variable (SvgElement) and its dynamic type (SvgText) in braces. Expanding a variable shows the properties and fields of the dynamic type.

Related

how to copy the grid data to object

I am trying to copy the grid data to one object.
Code :
object obj = GrdReport.ItemsSource;
PrepareDataForStackedChart1(obj);
The function is defined as
private void PrepareDataForStackedChart1(object categoies)
{
var Salespersons = (from cat in categoies
select cat.Salesperson);
}
I am getting error :
Cannot convert from 'lambda expression' to 'System.Linq.Expressions.LambdaExpression'
Can anyone tell me how I can access the object in a linq query?
Edit: Just happened to learn you are using a third party control (from your duplicate question) whose ItemSource property takes System.Object and not IEnumerable. In that case either cast your object (ItemSource) back to the original type, or maintain the original collection you used to bind the control somewhere and pass that collection to your PrepareDataForStackedChart1 method.
Some guess work:
1) Either
object obj = GrdReport.ItemsSource;
PrepareDataForStackedChart1((IEnumerable<Category>)obj);
private void PrepareDataForStackedChart1(IEnumerable<Category> categories)
{
var Salespersons = (from cat in categories
select cat.Salesperson);
}
2) or when you do
GrdReport.ItemsSource = GetCategories();
Copy a back up as well like this:
categories = GetCategories(); //categories is defined in proper scope.
GrdReport.ItemsSource = categories;
And later you do;
PrepareDataForStackedChart1(categories);
private void PrepareDataForStackedChart1(IEnumerable<Category> categories)
{
var Salespersons = (from cat in categories
select cat.Salesperson);
}
3) or may be you will get the collection from Items or Rows property (perhaps) defined on your GridView. Good luck..
Pre edit:
The error is because you cant enumerate a plain object. It has to be enumerable. Why are you passing an object value to your PrepareDataForStackedChart1 method? Instead can't you pass the IEnumerable itself? Try
var categories = GrdReport.ItemsSource.OfType<Category>();
PrepareDataForStackedChart1(categories);
private void PrepareDataForStackedChart1(IEnumerable<Category> categories)
{
var Salespersons = (from cat in categories
select cat.Salesperson);
}
I am assuming you have parent class Category

Set value in model when dynamically creating object of model

I have a bunch of models that may or may not have a property "CommonProperty". I want to set that property when I am creating a new object of a selected model. What I have so far, which works is:
ModuleItem model = db.ModuleItems.Find(ModuleItemID);
object o = GetModuleType(model.ControllerName);
private object GetModuleType(string ModelName)
{
string projectName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
Type classtype = Type.GetType(string.Format("{0}.Models.{1}", projectName, ModelName));
PropertyInfo[] properties = classtype.GetProperties();
var classObject = classtype.GetConstructor(new Type[] { }).Invoke(null);
return classObject;
}
What I want to achieve is to set CommonProperty:
o.CommonProperty = DistinctValue;
I tried creating a class that all of my models inherit from with a virtual method and each model then has an override method. Because its not static I can't call it directly and if I create a new ModelBase then when calling the method it doesn't get overriden by the type that object "o" is. I looked at creating an interface but 1 I don't even know how these work, and 2 (probably because of 1) I am not even able to create a way of doing this without build errors.
When stepping through the code I can see all the properties of "o" using the quickwatch or intellisense or whatever it's called. Clearly it is being recognised as the correct type. I can't seem to be able to call the method though because it's not a recognised (or set) type during build only during runtime and therefore I can't build the solution.
What I would do is create a base model (eg: BaseModel) for viewmodels that have the property CommonProperty then check whether the model is of type BaseModel then set the property
if (obj is BaseModel)
{
obj.CommonProperty = DistinctValue;
}
As it turns out I was way overthinking this. Typically the answer is ridiculously simple. No base model necessary, no overrides, no virtuals, no instances, dump it in a try catch and just set the value of the context object.
object o = GetModuleType(model.ControllerName);
db.Entry(o).State = EntityState.Added;
try
{
db.Entry(o).CurrentValues["CommonProperty"] = DistinctValue;
}
catch (Exception err) { }
I did have to make sure I set the state BEFORE setting a current value otherwise it wasn't in the context (or something like that).

Linq - How can i use "this" inside of a "select new" statement

Edited:
I'm querying some XML into objects recursively. Each object has a list of sub objects, and should refer to it's parent if it has one.
Example XML:
<object attribute1="text" attribute2="text"/>
<object attribute1="text" attribute2="text">
<object attribute1="text" attribute2="text">
<object attribute1="text" attribute2="text">
</object>
Example Linq:
private static List<MyObject> ParseMyObjects(XElement node, MyObject p)
{
List<MyObject> myobjs = (from x in node.Elements("object")
select new MyObject {
attribute1 = x.Attribute("attribute1 ").Value,
attribute2 = x.Attribute("attribute2 ").Value,
subObjects = ParseMyObjects(x, this), // the "this" key word can't refer to the MyObject being created in the query, but is there some other way of doing this?
parent= p
}).ToList();
return myobjs;
}
To accomplish this currently, I am recursively traversing the MyObjects list AFTER it has been queried and setting each parent (the "parent" line above is excluded).
I would simply prefer a more elegant solution of using the newly instantiated object within the Linq query if possible. Any ideas?
Edit:
To clarify (as BrokenGlass did in a comment), the this that the code comment is referring to is the instance of MyObject that is being created within the query
this can't work in a method marked static ever. There is no instance because the method is static.
I would simply prefer a more elegant solution of using the newly instantiated object within the Linq query if possible. Any ideas?
Just use XObject.Parent as in
parent = x.Parent
If you want the Parent member of the created MyObject instance to point to the instance itself, there are two ways to achieve this without adding code that iterates over the list after the Linq query:
1) Add a constructor that sets it up for you, e.g. the default constructor
public MyObject() {
this.Parent = this;
}
2) Add a fluent-interface style method for setting the parent, and invoke it in the query:
/* in class MyObject */
public MyObject WithSelfAsParent() {
this.Parent = this;
return this;
}
/* updated linq query */
List<MyObject> myobjs = (from x in node.Elements("object")
select new MyObject {
attribute1 = x.Attribute("attribute1 ").Value,
attribute2 = x.Attribute("attribute2 ").Value,
subObjects = ParseMyObjects(x),
}.WithSelfAsParent()).ToList();
Whether these are better than explicitly looping over the list is of course a matter of taste. I would probably just keep it simple and choose the loop, unless the assumption that the parent pointer is equal to this by default is obvious in the context of your MyObject class, which makes setting it in the default constructor the natural choice.
The solution for me was to harness the set of the subObjects property on MyObject.
class MyObject {
....
private List<MyObject> _subObjects = new List<MyObject>();
public List<MyObject> subObjects
{
get { return _subObjects ; }
set
{
_subObjects = value;
if(_subObjects != null)
{
foreach(MyObject o in _subObjects )
{
o.parent = this;
}
}
}
}
....
}
If anyone does know of a way to reference the newly created/selected object within the Linq syntax, I will mark your answer as the corrrect one.

Get Access property of a CodeElement

I'm writing an Add-in for VS 2010. Can't find answer for a question - How can i get the Access property of a CodeElement if it has that one.
I was trying reflection, but no results.
Ex. CodeElement is a class method
public void GetAccess (CodeElement codeElement)
{
object code = codeElement;
Type t = code.GetType();
t.GetProperty("Access") = vsCMAccess.vsCMAccessPublic;
}
But it doesnt work..
Help, please!
Access is only available on some types of CodeElements, so you'll need to check for the type of CodeElement you have, cast to the specific type and then retrieve the property.
Example:
if (codeElement.Kind == vsCMElementFunction)
{
return ((CodeFunction)codeElement).Access;
}
else if (codeElement.Kind == vsCMElementProperty)
{
return ((CodeProperty)codeElement).Access;
}

Entity Framework Optimistic Concurrency Exception not occuring

We have an ASP.Net MVC application that uses EF4 as its data access layer and we're seeing unexpected behaviour with regards to OptimisitcConcurrencyExceptions not being thrown when we think they should be.
We have simplified the problem down to the following code...
using System.Linq;
using Project.Model;
namespace OptimisticConcurrency
{
class Program
{
static void Main()
{
Contact firstContact = null;
using (var firstEntities = new ProjectEntities())
{
firstContact = (from c in firstEntities.Contacts
where c.LastName == "smith" select c).Single();
}
using (var secondEntities = new ProjectEntities())
{
var secondContact = (from c in secondEntities.Contacts
where c.LastName == "smith" select c).Single();
secondContact.Title = "a";
secondEntities.SaveChanges();
}
firstContact.Title = "b";
using (var thirdEntities = new ProjectEntities())
{
var thirdContact = (from c in thirdEntities.Contacts
where c.LastName == "smith" select c).Single();
thirdContact.Title = firstContact.Title;
//EXPLICITLY SET VERSION HERE
thirdContact.Version = firstContact.Version;
thirdEntities.SaveChanges();
}
}
}
}
This is a rather simple version of what happens in our MVC app, but the same problem occurs.
When we call SaveChanges on the thirdEntities, I expect the exception and nothing is being thrown.
Much more interestingly, when we attach the SQL Profiler, we see that the Version is being used in the where clause but it is thirdEntities Version value (the current one in the DB) being used, not the firstEntities values DESPITE it being explicitly set immediately before SaveChanges is called. SaveChanges is resetting the Version to be the retrieved value not the set value.
In the EDMX, the Version is set to have a StoreGeneratedPattern is set to Computed.
Anyone have any idea what is going on here?
This is a problem. Once the column is set to Computed you can't set its value in the application (you can but the value is not used).
Edit:
If you load entity from database it is by default tracked with the context. The context stores its original values. Original values are for example used for snapshot change tracking but they are also used as the only valid source of Computed properties. If you set Computed property in your entity the value is not used and original value is used insted. The workaround is to modify original value (before you modify anything else):
using (var context = new TestEntities())
{
var entityToUpdate = context.MyEntities.Single(e => e.Id == someId);
entityToUpdate.Timestamp = entity.Timestamp;
ObjectStateEntry entry = context.ObjectStateManager.GetObjectStateEntry(entityToUpdate);
entry.ApplyOriginalValues(entityToUpdate);
// set modified properties
context.SaveChanges();
}
Edit 2:
Btw. once you have both actually loaded timestamp and previously retrieved timestamp you can simply compare them in your application instead of doing it in the database.

Resources