Change Info Shown in VS 2010 DataTip - c#

I am attempting to find a way to alter the information that is shown in a DataTip in the VS 2010 Debugger. The purpose being that I would like to choose what property value is shown on the initial window of a DataTip.
For example, when hovering over a collection in debug mode I am presented with the Name of the collection followed by its Count property's value.
This is useful information, but when I am hovering over one of my custom objects I am only presented with a path providing the type of object it is (in my case something like BOS.SuggestedOrdersDataEntity.SuggestedOrdersEntity).
I would like to have this initial DataTip window contain the property that I would determine to be the most useful depending on what custom object it is. For instance it could be the case that for an object that is of type SuggestedOrdersEntity it would be more helpful for the DataTip to show the value of its VendorName property in place of BOS.SuggestedOrdersDataEntity.SuggestedOrdersEntity (similar to the way collections show their Count property). The goal is to not have to use the '+' expander to find the current value of the VendorName (or whatever property is most useful).
I would like to be able to alter the DataTips so that I can customize them to immediately show a specific property's value (just like Count shows for collections) without needing to expand and view all the properties.
Does anyone know if this is possible? I've done some researching on DataTips, but nothing I have found discusses customizing them in this way...

You can use the DebuggerDisplay attribute, examples here.
[DebuggerDisplay("{Name} - {StockSymbol}")]
public class Company
{
public string Name { get; set; }
public string StockSymbol { get; set; }
public IEnumerable<Employee> Employees { get; set; }
public Company(string name) { Name = name; }
}

Related

Sitecore, wrong type of inherited template field created by TDS

I have a problem with template inheritance:
I have base template (let say Parent) which contains the following field:
Theme (Droplist with query specified)
And template (Child) derived from it.
The issue is that once I inherited Parent, and generated model for it with TDS, I got:
public virtual string Theme {get; set;}
But expected to get Guid class. Once I swithced Theme field to type Multilist I got:
public virtual IEnumerable<Guid> Themes {get; set;}
Which has Guid type in it...
How can I tell to TDS(GlassMapper) to have Guid instead of string?
You've already figured out that you need to use a DropLink field type (which stores a guiGUID) instead of DropList (which just stores the value).
Instead of returning the GUID and then looking up the item again in Sitecore to then retrieve the values, you can have the TDS CodeGen templates return the linked item type instead by setting the object type in the Custom Data property field.
There are 2 main settings of interest:
type : For single linked items, e.g. DropLink. Generated code will output:
public virtual AssetLibrary.LookupValue MyFieldName { get; set; }
generic : For multiple linked items, e.g. MultiList field
public virtual IEnumerable<AssetLibrary.LookupValue> MyFieldName { get; set; }
Since most of the time you want a guid to resolve to a specific type, this saves some boilerplate code to lookup linked items and Glass will automatically resolve to the linked item.
Ok, finally, I found my mistake while writing this question... I used wrong type for Theme:
should use Droplink instead of Droplist.

Custom c# code in a Report

I am populating a report using an Object. Everything works fine, if my members are string, however, I have a few members, which are List<string>.
When I add these fields to the report (in designer, visual studio 2012) and run the report, they show as
'#Error'
Viewing the properties of the report, I can see that there is a 'custom code' tab, for which I've entered the following method to convert the list of strings into a array of string.
public string[] GetListItems(List<string> intList)
{
var s = intList.ToArray();
return s;
}
Then when I try and replace the field with an expression and enter the following:
=Join(Code.GetListItems(Fields!Aka.Value),",")
and then run the report, VS fails to build with the following:
Error 2 The Value expression for the textrun ‘Aka.Paragraphs[0].TextRuns[0]’ contains an error: [BC30456] 'GetListItems' is not a member of 'ReportExprHostImpl.CustomCodeProxy'.
Error 1 There is an error on line 0 of custom code: [BC30183] Keyword is not valid as an identifier.
Can anyone shed any light why this is?
That is C# code. Directly in the report you can only use Visual Basic. C# is avaliable as an external DLL.
For those who can't create go through the difficulties of implementing a third-party DLL. A simpler; but, a messier solution is as follows.
To summarize solution, you can create properties that returns a value that the reports can easily work with.
In my scenario, I had 2 classes:
public class Parent {
public Child { get; set; }
}
public class Child {
public string Name { get; set; }
}
The type that I was binding to my Report was Parent; however, I needed to access the Name property inside Child. In otherwords I needed to do:
Parent.Child.Name
This where I ran into the same problem that the OP ran into. Due to the scope of my project (a college project), I can't bother with third-party dlls or writing my own dll...
So what I did is add more properties to the Parent class.
public class Parent {
public Child { get; set; }
public string ChildName { get => Child.Name; }
}
public class Child {
public string Name { get; set; }
}
By adding an additional property to Parent that has an type that Reports can work with, I can now easily access the Child's Name through my Parentclass.
Of course this is messy; but, I'm in a situation where I can't go with the more complicated/time consuming dlls solution.
I just hope my instructors will allow this solution without penalty...
If you just created a report and showing an error code like
BC30016 labels are not valid outside of the method.
The reson in my case was that i have insert the random numerical value n the code property of a report1.rdlc
Hence to solve this type of error, goto report properties and remove the value from the code.

Hidden Workflow Arguments to System.Activities.ActivityBuilder

I have rehosted the Workflow designer, and the base activity that i load is the Activity Builder(workflowDesigner.Load (activityBuilder);)
I basically need to add in some details to the activity, and the value of which the user should not be able to edit (or may be even see on the designer surface). For this I am (currently) adding some arguments as follows where i can add in the extra information.
activityBuilder.Properties.Add (new DynamicActivityProperty
{
Name = "HiddenArgument",
Type = typeof (string),
Value = "Value that the user should not edit."
});
But as these arguments are visible on the designer surface in the Arguments Panel on the bottom of the designer, the user can edit this. i also have other arguments that the user is allowed to edit so therefore i cant disable the whole arguments pane.
I would just want to know how can i add my information to the workflow(and obviously save it in the *.XAML file) so that the user cant edit (or see) this information.
EXTRA DETAILS: I basically want something like, if i create a custom activity i can add properties with [Browsable(false)], which causes the user to not see the property on the right side pane but hold a value!
EditorBrowsableAttribute is what you would use in a normal argument on a regular Activity.
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public InArgument<string> Foo { get; set;}
[Browsable(false)] - Only this attribute avoid presentation of this argument in PropertyInspector.
[EditorBrowsable(EditorBrowsableState.Never)] - doesn't affect avialabitly of this argument from Property Inspector, it make the property inaccessible by intellisense.
[Browsable(false)]
public InArgument<string> Foo { get; set;}

Compile Time Type Assignment

I'm working on a custom validation framework for my WPF/C# application.
What I'm looking to do is to retrieve strings from the resource file where the viewmodel is declared, but in the actual validation code it self. This particular string is the same resource used by label on the editing UI Form.
My code works fine with the following syntax -
[Required(TypeRes = typeof(Resources))]
public string RequiredStringWithDesc { get; set; }
But what I"m looking for is something that is syntacticly cleaner looking. I was trying to use
const Type LocalRes = typeof(Resources);
[Required(TypeRes = LocalRes)]
public string RequiredStringWithDesc { get; set; }
Any suggestions on a simpler syntax? The old c++ DEFINE statement here would work well.
FYI: the reasons for going to this much work has to do with how we are doing localization and UI construction.
EDIT To answer a couple of questions about why are we doing this?
We are going to be using the same string from the resource file to -
On the edit screen, this is the label to identify the field.
In the datamodel, if there is a validation error, we are using this to correctly label the problem in the log file.
In the Viewmodel, we are reusing this label in the validation error message to reinforce where the problem is to the user.
This is part of a real time inspection system and some of the failure modes relate directly back to these data fields. So we can easily get the correctly localized label to apply to run-time fault messages
The general concept is that this simplifies presenting consistent messages to the user while only creating things once. With regards to validation attributes (and this question), we need to be able to get the Resource file type to load the correct message.
Create a new attribute class which inherits from the RequiredAttribute and set default values.
public class LocalizedRequiredAttribute : RequiredAttribute {
public LocalizedRequiredAttribute() { /* TypeDef = typeof(Resources);*/ }
}
public class MyModel {
[LocalizedRequired]
public string RequiredStringWithDesc { get; set; }
}

Dynamic options dialog (using reflection)

Does anyone know of a good component (C# WinForms) which would allow creating an options (settings) form, given a custom class with a bunch of properties? I am not looking for something shiny, but something merely better than a property grid. I can easily take care of the visual part, but I simply don't want to lose time doing reflection to add and bind controls if it already exists.
I am pretty sure I've seen a Visual Studio options-like form somewhere before, which was created dynamically (with some attributes attached to the properties of the class, to allow grouping and additional info).
[Edit] For example, I might have an options class:
public class Options : SerializableOptions<Options>
{
[Category("General")]
[Name("User name")]
[Description("Some text")]
public string Username { get; set; }
[Category("General")]
[Name("Log in automatically")]
public bool LogInAutomatically { get; set; }
[Category("Advanced")]
// ConnectionType is enum
public ConnectionType ConnectionType { get; set; }
// ...
}
After passing it to this form, it would create two panels ("General" and "Advanced"), with a CheckBox and a TextBox on the first panel, and one ComboBox (with all available enums) on the second panel.
If there isn't such a control, what do you guys use? Manually add, populate, format and bind controls for each option?
I'm not aware of any controls that allow you to do this, but it isn't difficult to do yourself. The easiest way is to create the dialog shell, a user control which acts as the base class for the options "panels", one (or more) attribute to control the name and grouping information, and an interface (which the user control implements).
Each of your custom options panels derives from the user control and overrides some sort of Initialize() and Save() method (provided by the user control). It also provides your attribute (or attributes) that determine the name/grouping information.
In the dialog shell, reflectively inspect all public types from your assembly (or all loaded assemblies) looking for types that implement your interface. As you find a type, get the attributes to determine where to place it in your grouping (easiest thing here is to use a tree view), call Activator.CreateInstance to create an instance of the user control and store it in the Tag property. When the user clicks on an entry in the grouping (a tree node), get the Tag and set the panel which contains the user control to the object in the Tag property. Finally, when the user clicks "OK" on the dialog, loop through the tree nodes, get the Tag property and call the Save method.
Update:
Another option would be to use a property grid control. It doesn't have a "pretty" UI look to it, but it is very functional, already supports grouping by a category attribute, and allows a great deal of flexibility. You could go with a single property grid that shows all of the options, or go with a "hybrid" approach with a tree view that groups by major functions (plugin, capability, etc.), probably based on the type. When the user clicks that node, give the property grid the object instance. The only drawback to this approach is that when changes are made to the property grid values they are "live" in that the underlying property is immediately changed, which means there is no concept of "Cancel" short of saving a copy of each value that could change and performing some type of "reset" yourself.
I don't know if such a control exists, but writing the required reflection code is really not that hard. E.g. something like this:
// the class for which to create an UI
public class MyClass
{
public string Text { get; set; }
public int ID { get; set; }
}
...
// basic reflection code to build the UI for an object
var obj = new MyClass() { Text="some text", ID=3};
foreach (var pi in obj.GetType().GetProperties())
{
var name = pi.Name;
var type = pi.PropertyType;
var value = pi.GetValue(obj, null);
//now setup the UI control for this property and display the value
}
I accidentally found something similar to this, I remebered that I had this problem a while ago and thought I should share it.
Here is a simple example: http://blog.denouter.net/2008/08/simple-reflection-form.html. It uses reflection to create several controls based on object's properties.

Categories