delphi 7 Items property - arrays

I come from Java background, where we have data structures with interfaces that if its collection it support certain behaviour, and a set has another.
while programming in Delphi I thed to hit a brick wall when it comes in asking the reflection about the behaviour of items, its very strange.
for example this code does not compile
menuOfSomeKind.Items.Add(t);
where menu of some kind is a component that has Items that contain other sub components, that are the menu entries.
if I want to dynamically edit this, meaning using the add behaviour, it says '[' expected but '.' found.
Could you please clarify this?

Probably menuOfSomeKind is TMenuItem and not TMainMenu
If you are adding an item to TMenuItem use MenuItem.Add(t);
If you are adding an item to TMainMenu use MainMenu.Items.Add(t);

There's a difference between TMainMenu/TMenu and TMenuItem.
var
mainMenu: TMainMenu;
menu: TMenu;
subMenu: TMenuItem;
begin
//***** This creates a new root menu
mainMenu.Items.Add(TMenuItem.Create);
//***** Essentially the same as mainMenu
menu.Items.Add(TMenuItem.Create)
//***** This adds a new submenu to an existing menu
subMenu.Add(TMenuItem.Create);
//***** This adds a new submenu to the first submenu of an existing menu
subMenu.Items[0].Add(TMenuItem.Create);
end;
Note that presented code compiles but will throw exceptions all over the place when run. For starters, none of the local variables are assigned.

Related

Winforms ObjectListView: inner OLVColumn instances Name property is empty string so I cannot show/hide columns by name

This question is an offshoot of: Localizing ObjectListView OLVColumn, impossible due to Empty Name property
For simplicity's sake, let's say my ObjectListView contains car information. User A wants to display only Make and Model columns. User B only wants to display Model and Year columns. These preferences would be saved to/loaded from an .ini file on the users' local machines.
I cannot loop through the columns of the ObjectListView and do if (col.Name == colNameFromIni) { col.Visible == true; } because the .Name property of every column is an empty string ("") and does not get serialized to the designer codebehind file. This never happens with any other Winforms control (Label, Button, etc.) They always get their .Name written to the designer codebehind.
In some sense, this is a flaw in Winforms itself, because OLVColumn inherits from System.Windows.Forms.ColumnHeader, and a traditional ListView has exactly the same problem. .Name is always an empty string for all columns.
I would like to patch our local build of ObjectListView.dll to force populate the .Name property, but I can't figure out how Winforms automagically knows the name of every control on the form. It somehow(?) knows the names of the OLVColumn objects since it can display them in the Edit Columns... dialog on the ObjectListView's context menu. I'm also a little fuzzy on where the best spot is to plug this in.
(Yes, per linked question at top I know that as a last resort, I can hardcode colXX.Name = "colXX"; for all columns in my source code, but future column additions are likely to get overlooked and a programmatic solution is much preferred.)
(See also: https://sourceforge.net/p/objectlistview/bugs/160/ : the ObjectListView author declared this a wont-fix so it is up to me (or us), I guess.)
As you point out, this is a bug which is not with the ObjectListView, but the underlying component. And a bug which is around since at least 2008! Therefore, I doubt it will ever be fixed by MS.
Actually, it is a problem with the Autogenerated code in the designer.
If you look at other components such as a button, then the autogenerated code adds a name such as this;
//
// button2
//
this.button2.Location = new System.Drawing.Point(458, 199);
this.button2.Name = "button2";
...
But for ColumnHeader (Listview) and OLVColumn (ObjectListView), then this is not done, so then you end up with this.
//
// olvColumn1
//
this.olvColumn1.AspectName = "Name";
this.olvColumn1.Text = "Name";
If you manually add the line
this.olvColumn1.Text = "olvColumn1";
Then the "problem" is solved.
Of course, you can't do this, because the designer will override the autogenerated code when you make any changes, and then you will lose these manually added lines. It is also not sustainable.
So I'm afraid you need to code around this with some kind of ugly solution. Some options are:
Use the Tag to store the name and compare against this.
Use the text instead of the name (not possible if you have multi
language support!)
Code the names column manually in the Constructor
Set the Text to be something like "ColName;ColText" and then in your
code separate these out.
I have done option 3 in the past, but only I was maintaining the code, so this was easy.
What you could do to ensure you don't have discrepancies is to add a check in your constructor to compare the actual number of columns with the number you expect (hard coded for), and throw an exception if they don't match. Also, not the best, but another way to highlight and reduce errors.
The workaround for this is to get the OLVColumns via reflection and set their column's Name property at runtime. Every OLVColumn is a form-level field, so just pick them out of the list returned by GetFields().
Dim allFieldInfos As FieldInfo() = GetType(FrmMain).GetFields(BindingFlags.NonPublic or BindingFlags.Instance)
For Each fi As FieldInfo In allFieldInfos
If fi.FieldType Is GetType(OLVColumn) Then
Dim instance As OLVColumn = fi.GetValue(Me)
For Each col As OLVColumn In fdlvMain.AllColumns
If ReferenceEquals(col, instance) Then
col.Name = fi.Name
End If
Next
End If
Next

Extjs 6.0 - ItemSelector: how to programmatically focus/highlight an element?

I have a ItemSelector component inside a Window. I have implemented a search functionality that dynamically finds the matching entry based on user's keyboard input.
Now I just want to highlight/focus such item inside the ItemSelector.
I'm looking for something like:
// when the search returned a result and got the related index in the store
function onSearchPerformed(index) {
var cmp = this;
cmp.itemSelector.setSelected(index); // here I'd be highlighting the entry
}
Example
Imagine a simple ItemSelector like this one taken from the web.
User types 'Delaw' and my search function detects that there is an entry with name Delaware and it's at position 3 in the store.
All I want to do is to programmatically highlight the row/entry 'Delaware' just as if you clicked on it.
This ux component uses a boundList, or better 2 of them.
A from and a toList.
You need to get a reference to the right boundlist.
More on that you will find here: http://docs.sencha.com/extjs/6.0.1/classic/src/ItemSelector.js.html
Basically you can do something like this:
https://fiddle.sencha.com/#view/editor&fiddle/24ec
afterrender: function(cmp){
Ext.defer(function(){
var boundlist = cmp.down('boundlist');
item = boundlist.all.item(1);
boundlist.highlightItem(item);
},300);
}
After you have a ref to the correct boundlist, you can simply highlight the item using:
http://docs.sencha.com/extjs/6.0.1/classic/Ext.view.BoundList.html#method-highlightItem
Take care that you may need to call following function before:
http://docs.sencha.com/extjs/6.0.1/classic/Ext.view.BoundList.html#method-clearHighlight
To find the correct item should't be too hard.
There are two ways to solve the issue
One is by following #devbnz answer, marked as correct. This is preferable, if you just want to graphically highlight the entry without triggering any event.
However, by hovering on other entries, you will lose the highlight on your current entry.
The second one, as suggested by #guilherme-lopes in the comments, may be preferable in cases in which you want the selection to act as if you actually clicked on an entry, which will trigger the selectionchange event and similar...
Depending on the situation, I ended up using either.

Assign instance id when the wpf app has multiple controls on page identified as one instance

Is it possible to use searchProperties.Add("Instance","1"); to assign instance id where the wpf application has multiple controls like buttons or combo boxes which are recognized as one instance of the control. If yes then how to do this? Any code sample is appreciated.
An addendum to AdrianHHH's excellent suggestion is to iterate through the FindMatchingControls collection and figure out which one is the one you want. If it's always collection[3] then you can identify it and act on it as such.
Your code would look like this:
var button = new WinButton(winWindowChild(mainParentCtName, childParentCtName));
//if you pass parents when you construct an object it can speed up find
button.SearchProperties.Add(/*any identifying properties*/);
var allButtons = button.FindMatchingControls();
//test code
foreach (var btn in allButtons)
Mouse.Click(btn); //watch this to figure out what order the buttons are iterating through, then remove loop
Mouse.Click(allButtons[3]);
Mouse.DoubleClick(allButtons[0]);
Mouse.Hover(allButtons[1]);

Trouble referencing movieClips

I am working on a flash project that dynamically generates navigation from an XML. For now I am trying to get it to work with arrays so that I can adapt it to xml once I know the logic works. I am new to as3 and learning has been a tiny bit bumpy. I have been searching for a solution to this but many of the examples I have seen have either been too simple to answer my question or too complex to understand since I am on the new side. This is the code I am working with.
var clientList:Array = new Array("Client1","Client2","Client3","Client4","Client5","Client6","Client7","Client8","Client9","Client10","Client11","Client12","Client13","Client14","Client15");
for each (var cName in clientList){
var newClientBtn:btnClientNav = new btnClientNav();
newClientBtn.x = workX;
newClientBtn.y = workY;
workY += newClientBtn.height;
newClientBtn.mcClientName.text = cName;
lContent.mcWork.addChild(newClientBtn.name);
trace(newClientBtn);
}
I can't fingure out how to properly refernce the dynamically created clips. I have a dynamic text box in the button but can't figure out how to reference it properly to change it, then my next issue will be referencing the buttons to make rollover and click code. I know this probably something simple to fix but I have been looking at it for too long and my eyes are starting to cross.. Thank you in advance for any advice you can give.
Why not store the clips you are creating in an object you can access later?
If you want to reference a movie clip by name though, one way to do it is:
var referenceMC:MovieClip = MovieClip(containerMC.getChildByName(“targetMC”));
If it was a text field or a button you were after, I believe you would do the same but instead cast the result of getChildByName to your desired control.
I also believe you want to add the button itself as a child, not pass its name into your addChild call?

Microsoft Surface: Adding IdentityTag to TagVisualizer shows a cross-hair. Why?

in my Surface application happens this:
When I put an IdentityTag onto my TagVisualizer, a white cross-hair appears. This TagVisualizer adds no TagVisualization when adding a Tag, it just calls some methods in its "VisualizationAdded"-Event.
In my other TagVisualizers before there were no cross-hair but they always had Visualizations added like this in the initialization of the TagVisualizer: tagDef.Source = new Uri("something.xaml", UriKind.Relative);
But how can I ged rid of this cross-hair?
I cannot find anything about it.
By the way, it looks like this: http://img80.imageshack.us/img80/4728/crosshairc.png
http://img80.imageshack.us/img80/4728/crosshairc.png'/>
I've just run into the same problem because I didn't want a TagVisualization to display when I put a tag down (I wanted some items to be displayed in an already displayed librarystack). I solved it by setting the source of the ByteTagDefinition to null
ByteTagVisualizationDefinition tvBlue = new ByteTagVisualizationDefinition();
tvBlue.Value = 02;
tvBlue.Source = null;
MainTagVisualizer.Definitions.Add(tvBlue);
This gets rid of the crosshair - and I assume will work for IdentityTags, although I have not tried.
the crosshairs are used as the default visualization if you dont specify a custom source. we did this in order to let developers get the layout & configuration working without having to first define the visualization. a crosshair was selected as a default visual because it can be helpful in validating your physical offset properties
-robert (former PM for the Surface controls)

Resources