Consider the following:
Public class Foo()
{
public BarClass Bar = new BarClass();
}
Here we have a simple class called Foo. Bar is a property of Foo of type BarClass. So when iterating through the code elements of Foo. Bar is simply a property and has no children.
However we do have access to the fullname of Bar.
How can I create a new CodeElement instance using the FullName property, so I can have access to the properties and methods (via the children collection) of Bar?
foreach (CodeElement child in Foo)
{
// Bar shows up as a property, and you can access the Fullname here...
}
Your question is not 100% clear (Bar is not a property of Foo, it is a field, and has no children). But to navigate the code elements using the automation model (EnvDTE) you need to cast EnvDTE.CodeElement to a specific type (such as EnvDTE.CodeClass, or EnvDTE.CodeType) and use the Members property, not the Children property. See: HOWTO: Navigate the code elements of a file from a Visual Studio .NET macro or add-in
Related
I have a window editor that holds nodes. I would like to open a custom inspector when one of these nodes is selected. The node class is a custom serializable class. Is this possible?.
It seems that custom inspectors can be created manually through the Editor.CreateEditor method but can't see how to let it appear docked like an usual inspector in the unity inspector window.
I would like to achieve the same behaviour that we have when we select a gameobject in sceneview that inmediately show properties for the object (Components, etc...) in the unity inspector.
Cheers
As I'm not sure what you're asking, here are multiple different solutions;
Selection
If you just want your nodes to become the focus of the hierarchy, then in your custom window's OnGUI method, use the code below;
[CustomEditor(typeof(NodeManager))]
public class NodeManager : EditorWindow
{
private static NodeManager window;
private Node[] m_nodes;
[MenuItem("Custom Windows/Node Inspector")]
public static void Init()
{
if(window == null)
window = GetWindow<NodeManager>("Node Manager", true, typeof(SceneView));
}
public void OnGUI()
{
m_nodes = GameObject.FindObjectsOfType<Node>();
foreach(Node node in m_nodes)
{
GUILayout.BeginHorizontal();
{
GUILayout.Label(node.name);
if (GUILayout.Button("Select"))
Selection.objects = new Object[] { node.gameObject };
}
GUILayout.EndHorizontal();
}
}
}
This adds a Button for each object in your custom window view, that will then select that object in the hierarchy.
Auto-Docking
I originally found the second response to this question, which goes into the details of parameters of the GetWindow method, and with this you can clearly see how to dock the window (I've converted it from JS to C# below).
(I looked fairly extensively in UnityEditor and UnityEditorInternal namespaces but couldn't find the Hierarchy or the Inspector).
GetWindow<T>(string title, bool focus, params System.Type[] desiredDockNextTo)
Which we can write for this example as;
EditorWindow.GetWindow<NodeInspector>("Node Test", true, typeof(SceneView));
This example docks the windows next to the SceneView window. This functionality can be combined with a custom inspector's OnInspectorGUI method, to automatically launch the custom node window, if it's not already open.
[CustomEditor(typeof(Node))]
public class NodeInspector : Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
NodeManager.Init();
}
}
Sorry if this isn't what you are looking for, if it's not then please give more details and I will amend my answer to better suit the question.
Hope this helped.
Has a possibility, you can make a custom ScriptableObject and Custom Editor for It, and when open the node inspector, just find a instance of the scriptable object and use Selection.selectedObject = scriptableObject, and in the custom editor, make a static field called 'editor' to draw inside.
It will work.
I have a quite large Flex application with a large set of views and I ceratain views I'd like to add shortcuts.
And i'm looking for something like:
<mx:Vbox>
<foo:Shortcut keys="ctrl+s" action="{bar();}"/>
....
</mx:VBox>
Is there any framwork or component already done that does something like this? I guess it should be too difficult to build? When building this I only want the shortcuts to be active when the view is visible. How do I detect this? What base class is best to inherit from when working with non visual components?
I don't know of any framework component that does that already, but the examples above should get you started if you try to build your own.
There's no need to inherit from any component for a non-visual component like the one you've described here (your "foo" class needs no parents.) There's nothing in the Flex framework you need to inherit from for this.
However you architect it, your foo class is going to have to take in and parse keyboard codes to listen for and accept one or more methods to call. All you have to do is figure out when to add and remove the event listeners that will call the passed-in methods.
To handle turning your keyboard events on and off based on visibility, just have your foo component bind to the "visible" property of it's parent and add/remove event listeners accordingly.
You might also consider having the listeners added when the component that foo is nested in is on the display list rather than just visible. To do this, simply added and remove your event listeners in one of the component lifecycle methods - probably commitProperties is the most appropriate.
I don't think this solution answer your question directly but anyway, to help solve your problem here is an example.
For instance, I've extended the TextArea component like so. This is the best I can do so far, it can definitely be improved upon. Like, I don't know how to make the cursor go to the end after the next shortcut is pressed.
public class TextArea extends mx.controls.TextArea
{
// the keysmap is an example dictionary holding keycodes
private var keysmap:*={
112 = "some text for F1"
,113 = "the text for F2!"
//etc, etc
}
public var handleKeyDown:Boolean =false;
public function TextArea(){
if(handleKeyDown ==true){
this.addEventListener(KeyboardEvent.KEY_DOWN,this.keydownHandler);
}
}
public function keydownHandler(e:KeyboardEvent):void{
if(e.keyCode >= 112 && e.keyCode <= 123){
e.currentTarget["text"] += String(keysmap[e.keyCode]) +" ";
}//focusManager.setFocus(this);
}
}
I can't give you a solution using MXML, however my first thought would involve a singleton static class with a Dictionary that contains a list of objects as its keys and dynamically created dictionaries as the value pairing that contain keys denoting the desired key press with a function reference as the value.
So, say you had a Sprite and you wanted to capture ctrl+s for save when focus is on that object, I would get the instance of that Singleton, and call a function such as registerKeyBinding passing in the Sprite, the keyCode you want, and your pre-defined callback:
private var registeredObjects:Dictionary = new Dictionary(true);
public function registerKeyBinding(targetObject:Object, keyCode:int, callback:Function) {
if (registeredObjects[targetObject]) {
Dictionary(registeredObjects[targetObject])[keyCode] = callback;
}
else {
registeredObjects[targetObject] = new Dictionary();
Dictionary(registeredObjects[targetObject])[keyCode] = callback;
targetObject.addEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
}
}
private function keyDownListener(e:KeyboardEvent):void {
if (e.ctrlKey == true) {
//calls the function if that key exists.
Dictionary(registeredObjects[e.target])[e.keyCode];
}
}
Can't say I've tested this, but it was just the first thing that popped into my head. You could then setup functions to deregister and delete keys from the dictionaries, check states of the objects in addition to the keyCodes, remove old listeners, and delete entire dictionaries when there is no longer a need for them. Hopefully this is at least a tiny bit helpful.
I'm using a tree control that I want to customize. The data items in the tree's dataProvider have a property name that should be used for labeling the node, and a property type that should be used to select one of several embedded images for use as an icon. The simplest way to do this is by using the labelField and iconFunction properties.
However, I wanted to get started with item renderers and open the door for adding more complex customization later, so I tried making my own item renderer. I extended the TreeItemRenderer class as follows and used it in my tree control:
class DirectoryItemRenderer extends TreeItemRenderer
{
[Embed("assets/directory/DefaultIcon.png")]
private static var _DEFAULT_ICON:Class;
// ... some more icons ...
override public function set data(value:Object):void
{
super.data = value; // let the base class take care of everything I didn't think of
if (value is Node) { // only handle the data if it's our own node class
switch ((value as Node).type) {
// ... some case clauses ...
default:
this._vSetIcon(_DEFAULT_ICON);
}
this.label.text = (value as Node).name;
}
}
private function _vSetIcon(icon:Class):void
{
if (null != this.icon && this.contains(this.icon)) {
this.removeChild(this.icon);
}
this.icon = new icon();
this.addChild(this.icon);
this.invalidateDisplayList();
}
}
This code has no effect whatsoever, icon and label in the tree control remain at their defaults. Using trace(), I verified that my code is actually executed. What did I do wrong?
Looking at the base mx.controls.treeClasses.TreeItemRenderer class, I see that in the updateDisplayList function the renderer gets it's icon and disclosureIcon classes from _listData:TeeListData. Instead of overriding the updateDisplayList function, try modifying the icon and disclosureIcon classes of the renderer's private _listData instance in your _vSetIcon method using the public accessors, like so:
private function _vSetIcon(icon:Class, disclosureIcon:Class = null):void
{
var tmpListData:TreeListData;
if (disclosureIcon == null) disclosureIcon = icon;
tmpListData = this.listData;
tmpListData.icon = icon;
tmpListData.disclosureIcon = disclosureIcon;
this.listData = tmpListData;
}
EDIT
Here is some clarification on the difference between data and listData. You'll have to excuse my omission of package names but I'm editing from my phone so its tough to look them up and I don't know the package names off the top of my head. data is defined in the context of a TreeItemRenderer in the IDataRenderer interface. You create a data renderer by implementing this interface and defining a public property data, which in this case is set by the parent control and contains some data and meta-data from the dataProvider to be rendered by the data renderer class.
listData is defined in the IDropInListItemRenderer interface as a property of type BaseListData and is realized in the TreeItemRenderer class as a property TreeListData. It differs from the data property in that it contains meta-data that describes the TreeListRenderer itself (icon, indent, open) as well as (I believe, I'll have to double check this later) a reference to the data item being rendered. I gather that It's used by the the TreeItemRenderer and I would imagine the parent list control for display update and sizing purposes. Someone is free to correct or add onto that if I'm incorrect or missed something, I'm going of what I remember drom the code.
In this case, you wanted to use meta-data from the data set from the data provider to modify data that determines the display of the renderer, so you would need to modify both.
I think the real confusion here however came from the fact that you extended the TreeItemRenderer class then tried to override functionality on the component in a manner the original developer didn't intend for someone to do, hence the unexpected results. If your goal is education and not ease of implementation you would probably be better served by extending the UIComponent class and using the TreeItemRenderer code as a reference to create a class that implements the same interfaces. That would be a real dive into the pool of custom component development.
I'd probably try something simple, as in this example from the Adobe Cookbooks. I notice that they override updateDisplayList, which may have something to do with your problems.
There's another example (for Flex 2, but looks applicable to Flex 3) that shows how to manage the default icons. It looks like you'll want to manage the icon yourself, setting the default icon styles to null, instead of trying to manipulate the superclass's icon property.
Update -- Looking at the source for TreeItemRenderer, commitProperties has the following before checking the data and setting up the icon and label:
if (icon)
{
removeChild(DisplayObject(icon));
icon = null;
}
Also, it looks like the setter for data calls invalidateProperties. Hence, your icon is wiped out when the framework gets around to calling commitProperties.
I have created a custom ASP.NET control ( derived from WebControls.TextBox).
I want to add a property to that control which will be of a type.
This property will actually always be some type of enum .
So when in the designer I look at the properties window of that control - I want to be able to assign value to that property by a selection from the specific enum .
So I want to see there the list of enumerators from the enumeration that I pass as ..
Example ( not actuall code that will compile .. just to show what I mean):
I have 2 enums :
enum MyEnumABC
{
A,B,C
}
enum MyColor
{
Red,Blue,Green
}
I have this control:
public class MyTextBox<T> : TextBox
{
public T Classification
{
get { }
set { }
}
}
Now I create a webpage which have following controls:
<Alex:MyTextBox runat=server id="alex" Classification=MyEnumABC.A></Alex:MyTextBox>
<Alex:MyTextBox runat=server id="alex2" Classification=MyColor.Red></Alex:MyTextBox>
The question is where can I actually pass the type to the constructor of that control ?
( since the page class is the one who calls the constructors of the controls.)
Where I actually need to set the type of alex1 to be of MyEnumABC , and the type of alex2 of type MyColor.
And the second question is how I make the VS2008 to support this in the designer of HTML ( so that when I type the Classification in the tag - it will open the write enum for selection of the value) and the property page of the control.
I hope you understand what I mean here.
Thanks .
The designer will support enum properties without you having to do anything special. Just specify the property in your control's code, give it all the usual attributes to allow it to be displayed in the property window and the property window will automatically display the enum values in a dropdown.
I am trying to come up with the best way to render some hierarchical data in to a nested unordered list using ASP.NET MVC. Does anyone have any tips on how to do this?
I suggest jquery tree view plugins for making it function like a tree, but as for render, just put it in a recursive lambda helper to do the nesting.
You mean... you want some sort of tree view?
You can actually get the treeview control to work... but you have to wrap it in server side form tag to function. You'll get the usual nastiness that that brings (like generated ids and viewstate) but it will work from a rendering perspective.
If you want to just create tags and nest them, it would be pretty easy to do with foreach() loops.
I believe currently there is no such control.... TreeViews are complex by nature. You can of course "draw" a hierarchy as much as you like using all sorts of repeaters and loops, but to achieve functionality of a tree view like the one in the Web forms toolbox... you have to wait !
Why don't you pass your model in the form of a tree to the view?
/// This is the model class
public class MyTreeNode<T>
{
public ICollection<MyTreeNode> ChildNodes {get;}
public T MyValue { get; set; }
bool HasChildren { get { return ChildNodes.Any(); } }
}
///This is the html helper:
public static string RenderTree<T>(this HtmlHelper html, MyTreeNode<T> root, Func<T, string> renderNode)
{
var sb = new StringBuilder();
sb.Append(renderNode(root.MyValue));
if (root.HasChildren)
{
foreach(var child in root.ChildNodes)
{
sb.Append(RenderTree<T>(html, child, renderNode));
}
}
return sb.ToString();
}
I didn't actually test this code, but it's about the idea. You can imagine creating your own recursive html helper to render a tree.
For that (rendering hierarchical menu, treeview, etc) i use recursive calls of custom component (ascx, or aspx in new preview5).
I give component first level of items (List of items), and component then check for each item in list if there's any child items and call itself with list of that child items.
You can build hierarchical graph of objects in controller, or just 1 dimensional list with ParentID property.