How to show icons on Tree Control in D365FO - axapta

Please how to show icons on FormTreeControl in Dynamics 365 For Finance and Operations
Here is my actual code, using to show icons in D365FO, #ResAppl Macro
public class IconsTree extends FormRun
{
public void init()
{
SalesTable _Table;
TreeItemIdx _TreeItemid;
super();
MyTreeView.deleteAll(); //This is my Tree Control on Form
MyTreeView.lock();
ImageListAppl dd = new ImageListAppl();
ImageRes imageRes = dd.image(#ImageFormButtonGroup);
MyTreeView.setImagelist(dd.imageList());
while select * from _Table
{
_TreeItemid = SysFormTreeControl::addTreeItem(MyTreeView, "Sales Order :" + _Table.SalesId ,FormTreeAdd::Root, _Table.RecId, #ImageOverlayYellowLock);
SysFormTreeControl::addTreeItem(MyTreeView, " Customer Account : " + _Table.CustAccount ,_TreeItemid , _Table.RecId);
SysFormTreeControl::expandTree(MyTreeView,_TreeItemid);
SysFormTreeControl::setOverlayImage(MyTreeView, _TreeItemid, imageRes);
}
}
}
and the result , no icons :

From what I have understood and what Microsoft indicates it's not allowed use image or icons on tree control in D365FO.
What is allowed build extensible controls, check this link Check box support in tree controls

Related

Switching between dynamically added user controls showing old values

Edit (more brief):
I have a control "configuration" with a tree view on the left and a list of panels on the right to which i add my controls. These elements are placed inside a table and surrounded by an ajax panel.
Let's say i have a tree node cars with two elements car1 and car2. When i click an item i save the ID and Type of the selected tree node inside hidden fields to be able to load the right user control on Page_Init
protected void Page_Init(object sender, EventArgs e)
{
var type = this.Request.Form["ctl00$MainContent$ctl00$typeId"];
var id = this.Request.Form["ctl00$MainContent$ctl00$entityId"];
if (!string.IsNullOrEmpty(type) && !string.IsNullOrEmpty(id))
{
this.LoadUserControl(type, id);
}
}
private void LoadUserControl(string type, string id)
{
if (Convert.ToInt32(type) != 0)
{
switch (Convert.ToInt32(type))
{
case (int)SkTopics.Product:
this.AddUserControl("../Modules/Product.ascx", this.Product, type, id);
break;
}
}
}
private void AddUserControl(string controlName, Panel panel, string type, string id)
{
// Init new user cotntrol
control = (BaseControl)this.LoadControl(controlName);
control.LoadEntityItem(Convert.ToInt32(id));
// Setting the user control ID
var replace = controlName.Replace("../Modules/", string.Empty);
string userControlId = replace.Split('.')[0] + id;
var targetControl = panel.FindControl(userControlId);
if (object.Equals(targetControl, null))
{
control.ID = userControlId;
control.DataBind();
panel.Controls.Add(control);
}
}
On LoadEntityItem the data for this car are collected from the database and the values are set as Text of textboxes. When i now switch to the second car, the new values are displayed.
Problem: I change the values inside the textboxes and press the save button to call my save method of the user control. From now on, when i switch to the car 1 again, the values for car 2 are still displayed, although the data for car1 are filled. tO see the data for car1 i have to switch to a complete different type of control and then back to the car1.
Another problem is, that i have a binary image inside the user control which Data i fill on init. When i swith to the the next car, where there i no image configured, i set the image data to null, but the image from the previous car i show. Onyl if i set a different image data the new image is displayed.
There is something else i noticed:
Inside the user control i call a javascript funtion but this one is only called on clicking the the save button. It seems that there is a different between the switch of the tree node and the save button click ?
ScriptManager.RegisterStartupScript(this, this.GetType(), "InitScrewPointsForDragging", "InitScrewPointsForDragging();", true);
I hope this was more brief than before.
It seems that the reason for the issue is some improper viewstate handling and after I disable the view state it is working correctly at my side. Here is the code that I updated to have it work at my side:
this.control.EnableViewState = false;
this.control.ID = userControlId;

Accessing Axapta report fields

I want to iterate over the fields of an Axapta report.
The problem I am facing is that I want to turn the fields visible and invisible before the report is shown. So I am overriding the Display method and add checkboxes to the Dialog.
I am looking for something that I can iterate over, like this
pseudocode:
public Object dialog(Object _dialog)
{
ListIterator it;
Dialog dialog;
;
it = new ListIterator (this.fields);
dialog = super(_dialog);
while (it.more())
{
dialog.addField(typeId(NoYesId),it.value);
it.next();
}
return dialog;
}
How can I access the fields of a report ?
Further information:
I am using Dynamics Ax 4.0
First, take a look on this question.
To access a report field, set the fields AutoDeclaration to Yes. Then the field is open for whatever:
stringControl.visible(...);
See report tutorial_FontInfo for an example of locating the control by name.
All controls of a report section can be accessed by number:
for (i = 1; i <= reportSection.controlCount); i++)
{
rc = reportSection.controlNo(i);
}

Wicket query API and write data to database on click AjaxEventBehavior

I have a list of professional league of legends player components (wicket panels) displayed in a grid and for each player, they have their own modal view(also a wicket panel). My problem is on the initial load of the site, since all wicket panels are being created (both player and player-modal panels), the modal panel has a listview of player info and this is taking quite some time to load all players info and write it to a database table. Is there some way that I can make the query happen only when a player is clicked? I thought about putting the query in an AjaxEventBehavior, but i'm getting a NotSerialiableException on my dao. I also considered adding the modal panel ONLY when the player is clicked (also using ajaxeventbehavior) and I couldn't figure out how to dynamically add the html:
What is the best approach so I don't have to query the api/database on initial load of the site?
Here is the Players Panel and you can see I am adding the modalpanel when the player panel is selected:
public PlayerPanel(String id, final IModel<?> model) {
super(id, model);
Label proName = (new Label("proName", model));
proName.add(new AttributeModifier("data-target", "#modal" + model.getClass().toString()));
add(proName);
//initializing daos for player
ApplicationContext context = new ClassPathXmlApplicationContext("Spring-Module.xml");
ProPlayersDaoJdbc proPlayersDao = (ProPlayersDaoJdbc) context.getBean("proPlayersDaoJdbc");
ProGamesDaoJdbc proGamesDao = (ProGamesDaoJdbc) context.getBean("proGamesDaoJdbc");
ArrayList<Players> allPlayers = (ArrayList<Players>) proPlayersDao.listPlayers();
final ArrayList<Games> games = new ArrayList<Games>();
for(Players p : allPlayers){
if(p.getProName().equals(model.getObject().toString())){
region = p.getRegion();
player = p;
Image proImage = new Image("proImage", p.getThumbnailPath());
proImage.add(new AttributeModifier("src", p.getThumbnailPath()));
proImage.add(new AttributeModifier("data-target", "#modal" + model.getObject().toString()));
try {
ArrayList<Games> gamesList = updateGamesPlayed(player.getSummonerId());
for(Games game : gamesList){
games.add(game);
}
} catch (RiotApiException e) {
e.printStackTrace();
}
add(proImage);
}
}
if(!games.isEmpty()){
for(Games game : games){
proGamesDao.create(game);
}
}
add(new ModalPanel("modalPanel", model));
}
The updateGamesPlayed(...) method queries the API and the proGamesDao.create(game) writes it to the db table.
You could have player image/link on click method making database query, set the result as default model object of child panel, and have page or grid refresh via target.add. on the child panel, you could control the size.

SDL Tridion 2011: Dynamically fill or add a metadata field using a C# TBB

Is it possible to set the value of a metadata field dynamically from a TBB? Or is it possible to dynamically add a metadata field that does not necessarily exist on a schema from a TBB?
The reason I want to do this is that I am using DD4T and I want to have the breadcrumb automatically added into the DD4T xml.
I have tried the following:
public override void Transform(Engine engine, Package package)
{
Initialize(engine,package);
var page = GetPage();
string output = page.OrganizationalItem.Title;
var parent = page.OrganizationalItem as StructureGroup;
while (parent != null)
{
output = GetLinkToStructureGroupIndexPage(parent) + Separator + output;
parent = parent.OrganizationalItem as StructureGroup;
}
// I tried this to dynamically add the field
//var metadata = page.Metadata.OwnerDocument.CreateElement("breadcrumb");
//metadata.InnerText = output;
//page.Metadata.AppendChild(metadata);
//I tried this to dynamically set an existing field on the schema
foreach (XmlNode xml in page.Metadata)
{
Log.Debug("Metadata field:" +xml.Name);
if(xml.Name == "breadcrumb")
{
xml.InnerText = output;
}
}
package.PushItem(Package.PageName, package.CreateTridionItem(ContentType.Page, page));
}
However, neither of these methods seem to work. Is this impossible?
DD4T has utility class FieldsBuilder with AddFields method where you can inject additional metadata. DD4T has a TBB which does update component metadata from Folder Metadata and it is called InheritMetadataComponent.
You could take a look at this here and you could implement the same:
http://code.google.com/p/dynamic-delivery-4-tridion/source/browse/trunk/dotnet/DD4T.Templates/InheritMetadataComponent.cs
FieldsBuilder.AddFields(component.MetadataFields, tcmFields, 1, false, mergeAction, Manager);
The easiest approach is to create a template class which implements DD4T.Templates.Base.BasePageTemplate. In that class, you implement the method TransformPage, which takes a DD4T page as its argument. You can access the 'TCM page' using the method GetTcmPage().
Example:
using TCM = Tridion.ContentManager.CommunicationManagement;
using Dynamic = DD4T.ContentModel;
public class MyTemplate : BasePageTemplate
{
protected override void TransformPage(Dynamic.Page page)
{
TCM.Page tcmPage = GetTcmPage();
string breadCrumbs = GetBreadCrumbs (tcmPage); // TODO: implement GetBreadCrumbs
Field f = new Field();
f.Name = "breadCrumbs";
f.FieldType = FieldType.Text;
f.Values.Add(breadCrumbs);
page.MetadataFields.Add("breadCrumbs", f);
}
}
page.MetadataFields.Add(name, field); should work if your template extends the DD4T.Templates.Base.BasePageTemplate
You can also take a look at the source of the Add inherited metadata to page TBB in DD4T, that also shows a way of adding Metadata which gets published to the broker.

How to get the form object in a ListPageInteraction class?

Working on Microsoft Dynamics AX 2012.
I have a listpage form which has a referenced ListPageInteraction class, just wanted to change the label / caption of a few control. For this I need to do something like:
element.form().design().control('<YourControlName>');
but I cant get this method on the ListPageInteraction class. I have decided to work on the class's initialized method. However there is no way to get to the form from there, how can I get to the controls and set labels?
common = this.listPage().activeRecord('Table');
if(common.isFormDataSource())
{
fds = common.dataSource();
fds.formRun().control(fds.formRun().controlId('ControlOfScreen')).
userPromptText('New Description');
}
Another example from projProjectTransListPageInteraction.initializeQuery() perspective changing the label of TransDate field from grid on form projProjectTransactionsListPage
public void initializeQuery(Query _query)
{
QueryBuildRange transDateRange;
// ListPageLabelChange =>
Common externalRecord;
FormDataSource frmDs;
FormRun formRun;
FormControl frmCtrl;
// ListPageLabelChange <=
;
queryBuildDataSource = _query.dataSourceTable(tableNum(ProjPostTransView));
transDateRange = SysQuery::findOrCreateRange(queryBuildDataSource, fieldNum(ProjPostTransView, TransDate));
// Date range is [(today's date - 30)..today's date] if not showing transactions for a particular project.
// Date range is [(dateNull())..today's date] if showing transactions for a particular project so that all transactions are visible.
transDateRange.value(SysQuery::range(transStartDate, systemDateGet()));
this.linkActive(_query);
// ListPageLabelChange =>
externalRecord = this.listPage().activeRecord(_query.dataSourceTable(tableNum(ProjPostTransView)).name());//No intrisic function for form DS?
if(externalRecord.isFormDataSource())
{
frmDs = externalRecord.dataSource();
formRun = frmDs.formRun();
if(formRun)
{
frmCtrl = formRun.design().controlName(formControlStr(projProjectTransactionsListPage,TransDate));
if(frmCtrl)
{
frmCtrl.userPromptText("newName");
}
}
}
// ListPageLabelChange <=
}
I don't think it is possible to get the FormRun object from ListPageInteraction.
If you were able to do it the rest would be easy:
FormControl fc = formRun.design().controlName(formcontrolstr(formName, controlName));
// etc.

Resources