X++ Dialog Field Lookup Override Error DialogControl.Control Cannot be Called From Server - dialog

First off, the code displayed below, extracted from where it is sitting in our AX, WORKS. Both the class creating the dialog and the class containing the lookup are set to run on "Called From". The class where the dialog method sits is an abstract class. Could that cause this error? The parent class also does not extend RunBase. Not sure if that makes a difference or not.
I am receiving this error, "The method DialogControl.control cannot be called from the server; use methods on the DialogField class instead", when attempting to add a lookup override to a dialog field.
Any help or workarounds would be greatly appreciated.
protected boolean dialog()
{
Dialog dialog = new Dialog("My Dialog", this);
DialogField myField;
boolean ok;
myField = dialog.addFieldValue(extendedTypeStr(MyStringType),
"DefaultValue", "FieldCaption", "FieldHelp");
myField.registerOverrideMethod(
methodStr(FormStringControl, lookup),
methodStr(MyClassName, MyLookupMethod),
new MyClassName());
ok = dialog.run();
}
private void MyLookupMethod(FormStringControl _control)
{
SysTableLookup sysTableLookup;
QueryBuildDataSource queryBuildDataSource;
Query query = new Query();
queryBuildDataSource = query.addDataSource(tablenum(CustTable));
sysTableLookup = SysTableLookup::newParameters(tablenum(CustTable), _control);
sysTableLookup.addLookupfield(fieldnum(CustTable, AccountNum), true);
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();
}

Ok, I finally found this. Thought I'd post the answer to help others.
While the class is set to Called From, as is the action menu item that calls it, it was re-instantiating itself using a construct method. The static Construct method was set as a server method.

Related

In D365/X++, why is '(' invalid when I use "this" to indicate the variable lives on the instance?

I have the following class:
public class MyDialogSelect extends RunBase
{
private DialogField nameField;
// Snipped for brevity
public Object dialog()
{
Dialog dialog = super();
nameField = dialog.addField(extendedTypeStr(CustName));
// Snipped for brevity
return dialog;
}
public void dialogSelectCtrl()
{
CustTable customerTable = CustTable::find(accountField.value());
nameField.value(customerTable.name());
// Snipped for brevity
}
}
This compiles and works as expected.
However, I prefer using the keyword this to indicate when variables belong to the instance, so I try changing it this to:
public class MyDialogSelect extends RunBase
{
private DialogField nameField;
// Snipped for brevity
public Object dialog()
{
Dialog dialog = super();
this.nameField = dialog.addField(extendedTypeStr(CustName));
// Snipped for brevity
return dialog;
}
public void dialogSelectCtrl()
{
CustTable customerTable = CustTable::find(accountField.value());
this.nameField.value(customerTable.name());
// Snipped for brevity
}
}
But, this won't compile, instead resulting in Invalid token '('..
However, if I remove this before nameField.value(customerTable.name());,
it works as expected again. (Note: I still indicate this in this.nameField = dialog.addField(extendedTypeStr(CustName));).
Why won't it compile when I include this before a property which invokes a method?
I've also observed this with this.nameField.enabled(false) also failing.
Is there a more general rule or principle I should understand here about when x++ allows, disallows, or requires this?
You cannot use this to reference instance variables in X++. Like in C++.
You can (and must) use this to refer to instance methods.
This refers to the context of the development, in your example, this refers to the class as a whole. Of you add another method, you would call that method using this.
With latest form pattern changes, I believe the MSFT recommendation is to use dialog form pattern instead of class to generate dialog.

Xamarin Forms - CustomObject, XAML Initialization, Setter not called, DependencyProperty, I'm lost?

I have a problem and I searched a solution about it. Lucky, I red lot of post about it but I'm lost with the explaination I found. The initale problem is coming from a personal project about the polyline of the Xamarin.Forms.Map where the initialization is realized by a binding from the XAML part..
Let me be clear by an example :
I have an object CustomMap.cs which inherit from Xamarin.Forms.Map (This file is in the PCL part -> CustomControl/CustomMap.cs)
public class CustomMap : Map, INotifyPropertyChanged
{
public static readonly BindableProperty PolylineAddressPointsProperty =
BindableProperty.Create(nameof(PolylineAddressPoints), typeof(List<string>), typeof(CustomMap), null);
public List<string> PolylineAddressPoints
{
get { return (List<string>)GetValue(PolylineAddressPointsProperty); }
set
{
SetValue(PolylineAddressPointsProperty, value);
this.GeneratePolylineCoordinatesInner();
}
}
// ...
}
So the Xaml part of the page, where the control is called, looks like that:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:control="clr-namespace:MapPolylineProject.CustomControl;assembly=MapPolylineProject"
x:Class="MapPolylineProject.Page.MainPage">
<ContentPage.Content>
<control:CustomMap x:Name="MapTest" PolylineAddressPoints="{Binding AddressPointList}"
VerticalOptions="Fill" HorizontalOptions="Fill"/>
</ContentPage.Content>
</ContentPage>
The Csharp part:
public partial class MainPage : ContentPage
{
public List<string> AddressPointList { get; set; }
public MainPage()
{
base.BindingContext = this;
AddressPointList = new List<string>()
{
"72230 Ruaudin, France",
"72100 Le Mans, France",
"77500 Chelles, France"
};
InitializeComponent();
//MapTest.PolylineAddressPoints = AddressPointList;
}
}
So, everything is fine if I edit the PolylineAddressPoints from the object instance (if the commented part isnt' commented..), but if I init the value from the XAML (from the InitializeComponent();), it doesn't work, the SetValue, in the Set {}, isn't called..
I then searched on the web about it and get something about the Dependency Properties? or something like that. So I tried some solutions but, from WPF, so some methods, such as DependencyProperty.Register();. So yeah, I can't find the way to solve my problem..
I also though about something, if DependencyProperty.Register(); would exists in Xamarin.Forms, then it means I would have to do it for each values? Because, if every value has to be set by a XAML binding logic, it would not work, I would have to register every value, doesn't it?
I'm sorry if I'm not clear, but I'm so lost about this problem.. Please, do not hesitate to ask for more details, thank in advance !
I finaly got a solution just over here => Ignore the Binding initialization
Copy paste from Stackoverflow. This following answer was given by Stephane Delcroix, thank to him !
There are multiple questions in this:
Why is the property setter never called when using Xaml ?
Am I properly defining my BindableProperty ?
Why is my binding failing ?
Let me answer them in a different order.
Am I properly defining my BindableProperty ?
The BindableProperty declaration is right, but could be improved by using an IList<string>:
public static readonly BindableProperty PolylineAddressPointsProperty =
BindableProperty.Create(nameof(PolylineAddressPoints), typeof(IList<string>), typeof(CustomMap), null);
but the property accessor is wrong, and should only contains this:
public IList<string> PolylineAddressPoints
{
get { return (IList<string>)GetValue(PolylineAddressPointsProperty); }
set { SetValue(PolylineAddressPointsProperty, value); }
}
I'll tell you why while answering the next question. But you want to invoke a method when the property has changed. In order to do that, you have to reference a propertyChanged delegate to CreateBindableProperty, like this:
public static readonly BindableProperty PolylineAddressPointsProperty =
BindableProperty.Create(nameof(PolylineAddressPoints), typeof(IList<string>), typeof(CustomMap), null,
propertyChanged: OnPolyLineAddressPointsPropertyChanged);
And you have to declare that method too:
static void OnPolyLineAddressPointsPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
((CustomMap)bindable).OnPolyLineAddressPointsPropertyChanged((IList<string>)oldValue, (IList<string>)newValue);
}
void OnPolyLineAddressPointsPropertyChanged(IList<string> oldValue, IList<string> newValue)
{
GeneratePolylineCoordinatesInner();
}
Why is the property setter never called when using Xaml ?
The property, and the property accessors, are only meant to be invoked when accessing the property by code. C# code.
When setting a property with a BindablePrperty backing store from Xaml, the property accessors are bypassed and SetValue() is used directly.
When defining a Binding, both from code or from Xaml, property accessors are again bypassed and SetValue() is used when the property needs to be modified. And when SetValue() is invoked, the propertyChanged delegate is executed after the property has changed (to be complete here, propertyChanging is invoked before the property change).
You might wonder why bother defining the property if the bindable property is only used by xaml, or used in the context of Binding. Well, I said the property accessors weren't invoked, but they are used in the context of Xaml and XamlC:
a [TypeConverter] attribute can be defined on the property, and will be used
with XamlC on, the property signature can be used to infer, at compile time, the Type of the BindableProperty.
So it's a good habit to always declare property accessors for public BindableProperties. ALWAYS.
Why is my binding failing ?
As you're using CustomMap as bot View and ViewModel (I won't tell the Mvvm Police), doing this in your constructor should be enough:
BindingContext = this; //no need to prefix it with base.
As you're doing it already, your Binding should work once you've modified the BindableProperty declaration in the way I explained earlier.

Changing text field of button in for loop

I'm making a level select screen and I need the text field to display different level numbers for each level. I don't really see what I'm doing wrong here, but I'll go over what I did and post the relevant code.
I have a button class (linked) and inside the symbol I have a dynamic text field. I have two classes of relevance, LevelSelectScreen and LevelSelectButtons (pretty self-explanatory what they are). I thought it would be really easy to change the text if I did it inside the LevelSelectButtons class, by simply doing levelText.text = "Wanted Text", where levelText is the given instance name for my button (just a text field on top of my graphic for the button). Unfortunately, this gives the oh so common and annoying error: TypeError: Error #1009: Cannot access a property or method of a null object reference.
I tried doing virtually the same thing in my LevelSelectScreen class during my loop, but I got the same error. Help on how to get this levelText to work is greatly appreciated! Here is the relevant code.
LevelSelectScreen
public class LevelSelectButtons extends SimpleButton {
public var levelNumber:int;
public var levelSelectScreen:LevelSelectScreen;
public function LevelSelectButtons(i) {
x = 200;
y = 100 + 50*i;
addEventListener(MouseEvent.CLICK,LevelSelectClicked,false,0,true)
levelNumber = i;
levelText.text = "Level" + i;
}
}
LevelSelectScreen
public class LevelSelectScreen extends MovieClip {
public var levelSelectButtons:LevelSelectButtons;
public var mainMenuButton:MainMenuButton;
public function LevelSelectScreen() {
for (var i:int = 1; i<=2; i++)
{
levelSelectButtons = new LevelSelectButtons(i);
addChild(levelSelectButtons);
}
}
}
You can't have a dynamic text field in a SimpleButton.
Annoying, I know.
Simple fix would be to have LevelSelectButton wrap a SimpleButton instead of extend it. Then your text field would be inside LevelSelectButton on top of a text-less SimpleButton. (Be sure to set mouseEnabled to false on the text field so it doesn't interfere with mouse events on the SimpleButton.
A more complex option would be to write your own custom button class.
It's not actually that difficult, but might be overkill for what you're trying to do here.
its because you haven't declared levelText variable and you are trying to access it, therefor Cannot access a property or method of a null object reference.

OutOfMemory error , use lwuit

I have some button on my form. When I click on every buttons run new form with same buttons. When I am clicking many times, show error OutOfMemory.
I think this is because I create a lot of form objects.
May be can clear stack or use form from stack if form is there?
You are keeping pointers (references) to old components which causes a memory leak. Make sure never to store components as members of your class unless you clear them later.
you need to use the Singleton pattern for your code. In Singleton Pattern, It will create only one object of your Form Class. If the object is null then it will create a new one else , it will return the current one. For this kindly refer to following code.
// Private Constructor
private static myForm thisForm = null;
private myForm()
{
thisForm = this;
}
// Now to Create Object, you need to create following getInstance Method
public static myForm getInstance()
{
if ( thisForm == null )
{
thisForm = new myForm();
}
return thisForm;
}
try above logic in your whole code. Your OutOfMemory Problem will 100% get solved.

Getting DefaultView through client object model

I want to load fields of the default view for Sharepoint list through client object model (I am using Silverlight). Here are some relevant things I've found (on msdn here):
class List has property DefaultViewUrl [of type string]
class List has method GetView(Guid)
class List has property Views [of type ViewCollection]
class ViewCollection has method GetById(Guid)
class ViewCollection has method GetByTitle(string)
class View has property DefaultView [of type bool]
That's everything I was able to find. As you can see there is no direct way of getting DefaultView (there is missing DefaultViewId property on List or GetByUrl(string) method on ViewCollection).
Seems to me as the only solution is to iterate through List.Views collection and check DefaultView property on each View. Which is kind of...well, inefficient...
Did I miss something? Anyone see some straigh solition?
Thanks for ideas.
Try LoadQuery using a LINQ statement
For Example:
private IEnumerable<View> viewQuery = null;
public void LoadDefaultView()
{
using (ClientContext ctx = ClientContext.Current)
{
list = ctx.Web.Lists.GetByTitle("YourList");
viewQuery = ctx.LoadQuery(list.Views
.Include(v => v.Title) // include more lamda statements here to populate View Properties
.Where(v => v.DefaultView == true));
ctx.ExecuteQueryAsync(LoadDefaultViewSuccess, LoadDefaultViewFailure);
}
}
private void LoadDefaultViewSuccess(object sender, ClientRequestSucceededEventArgs args)
{
// should only be one View in views
View defaultView = viewQuery.FirstOrDefault();
// use default.Title here
}
private void LoadDefaultViewFailure(object sender, ClientRequestFailedEventArgs args)
{
// handle failure here
}
MSDN SharePoint 2010 Silverlight COM article here
http://msdn.microsoft.com/en-us/library/ee538971.aspx
What about SPList.DefaultView? The SPList DefaultView member is an SPView object (not bool)

Resources