I want to make a Button.
I have a EDT "Resigning", which can't be edited, it only can be edited once and that when I press the button.
When clicking the button a Dialog shall Pop up where I can type in the date.
I have to write a class I think, but I am struggling a lot...
With Kind Regards
Khashayar
you can write the code in clicked method of the button.
Here a simple job to do that:
static void StackOverflow(Args _args)
{
Dialog dialog;
DialogField dialogDate;
date newDate;
;
dialog = new Dialog("Set new date");
dialogDate = dialog.addField(ExtendedTypeStr("YourEDTName"), "New date:");
if (dialog.run())
{
newDate = dialogDate.value(); //Get value of new date.
//Here code to update your table
}
}
To prevent from overwriting existing value you can modify your method as following:
public void clicked()
{
Dialog dialog;
DialogField dialogDate;
date newDate;
;
if (EmploymentTable.Resigning == dateNull())
{
dialog = new Dialog("Set new date");
dialogDate = dialog.addField(ExtendedTypeStr("YourEDTName"), "New date:");
if (dialog.run())
{
newDate = dialogDate.value(); //Get value of new date.
//Here code to update your table
}
}
else
{
warning("Value already exists.");
}
}
The code above is checking whether value already exists, before allowing to assign new value.
More better approach is disabling the button if value already exists. To do this write a method to disable/enable your button and call it in active method on form datasource.
Related
I'm using JFXDatePicker extends DatePicker and want to change default date when clicking Calendar Icon.
The default is the current date and I want to change it to a specific date
by code (It will save a little time when choosing a date in 195x for
example. I disable the Editable so can't type in textfield) And I
don't want to use .setvalue() because it will display that date when
the form was called.
I've used this code but didn't work.
birthday = new JFXDatePicker(LocalDate.of(1980, Month.MARCH, 11));
[http://i228.photobucket.com/albums/ee83/ThamVanTam/JFXDatePicker_zpscdgns2b6.png]
You can simplify #KirantosTera's code by listening to the pickers showingProperty then clearing the editor using Platform.runLater()
JFXDatePicker jfxDatePicker = new JFXDatePicker();
jfxDatePicker.showingProperty().addListener((observableValue, wasFocused, isNowFocus) -> {
if (isNowFocus && jfxDatePicker.getValue() == null) {
jfxDatePicker.setValue(LocalDate.now().minusYears(18));
Platform.runLater(()->{
jfxDatePicker.getEditor().clear();
});
}
});
Unfortunately there is no public api to navigate in the popup content. That's supported by an internal class DatePickerContent, which has a method goToDate(LocalDate, boolean). If you are allowed (and daring enough :) to use internals, you can do so in a onShown handler (to make certain that skin's onShowing listener doesn't interfere):
datePicker.setOnShown(e -> {
if (datePicker.getValue() == null && datePicker.getSkin() instanceof DatePickerSkin) {
DatePickerSkin skin = (DatePickerSkin) datePicker.getSkin();
DatePickerContent popupContent = (DatePickerContent) skin.getPopupContent();
popupContent.goToDate(LocalDate.now().minusYears(18), true);
}
});
Note that this requires to open com.sun.javafx.scene.control.DatePickerContent
Here is my solution, it's not perfect but still good for my issue:
//Setting datepicker :
birthday.setDayCellFactory(picker -> new DateCell() {
#Override
public void updateItem(LocalDate date, boolean empty) {
super.updateItem(date, empty);
//Setting date 18 years ago
LocalDate today = LocalDate.ofYearDay(LocalDate.now().getYear() - 18, LocalDate.now().getDayOfYear());
//Disable future date
setDisable(empty || date.compareTo(today) > 0);
}
});
//Setting actual value
birthday.setValue(LocalDate.ofYearDay(LocalDate.now().getYear() - 18, LocalDate.now().getDayOfYear()));
//Cover the value by text
String pattern = "dd-MM-yyyy";
formatCalender.format(pattern, birthday);
birthday.getEditor().setText("Date Of Birth");
birthday.setPromptText(null);
Table has one date field. I have two form name as formA and formB ,formA has textbox and button. formB has grid with date field.
So my question is if I enter date in textbox and clicked the button of formA, entered date should be assign in grid of formB. I added table datasource of both forms. Please help me out on this.
Although behavior described by you seems to be not so standard in terms of AX, I would suggest you to use dialog form as a FormA (rather than regular form). That way you respect best practices and desired behavior is achieved easier.
Create class extending RunBase class with date field:
class FormADialog extends RunBase
{
DialogField fieldDate;
TransDate transDate;
}
Here is how we construct form controls:
protected Object Dialog()
{
Dialog dialog = super();
fieldDate = dialog.addField(extendedTypeStr(TransDate), 'Date');
return dialog;
}
The following method will retrieve values from Dialog:
public boolean getFromDialog()
{
transDate = fieldDate.value();
return super();
}
Processing logic goes here:
public void run()
{
FormBTable formBTable;
ttsbegin;
select firstOnly forUpdate formBTable;
formBTable.Date = transDate;
formBTable.write();
ttscommit;
}
The only missing thing is entry point for dialog class (represents FormA):
public static void main(Args _args)
{
FormADialog formADialog = new FormADialog();
FormDataSource formDataSource;
if (formADialog.prompt())
{
formADialog.run();
// FormB should contain menu item for dialog class for the following code
if (args && args.record() && args.record().dataSource())
{
formDataSource = args.record().dataSource();
formDataSource.research();
}
}
}
Now clicking on dialog button will update grid.
If you insist on use of approach with two regular forms. I will think of linkActive() method at the datasource of the second form. Take a look at
Tutorial Form Dynalink. A record change in the parent form notifies the child form, making it call the linkActive method which in turn calls the executeQuery method at the child table datasource.
Another approach could be as follows.
For passing parameters from one form to another a special class Args is usually used.
Initiator form prepares data for transfer within clicked() method of button control:
void clicked()
{
Args args;
FormRun formRun;
args = new Args();
args.parm(dateField.text());
args.name(formStr(FormB));
formRun = classFactory.formRunClass(args);
formRun.init();
formRun.run();
formRun.wait();
super();
}
Receiving endpoint should listen at init() method of FormB:
public void init()
{
Date passedValue;
super();
// check presence
if (element.args())
{
passedValue = str2Date(element.args().parm(), 123);
}
}
Take a look at axaptapedia.com article to see how we can pass complex set of parameters within custom made class.
I'm implementing a DynamicItemStart button inside a Menu Controller. I'm loading the dynamic items for this button when Visual Studio starts. Everything is loaded correctly so the initialize method is called an I see all the new items in this Dynamic button. After the package is completely loaded I want to add more items to this Dynamic button, but since the package is already loaded the initialize method is not called again and I cannot see the new items in this Dynamic button. I only see the ones that were loaded when VS started.
Is there any way that I can force the update of this Dynamic button so it shows the new items?. I want to be able to update the VS UI after I added more items but outside the Initialize method.
The implementation I did is very similar to the one showed on this msdn example:
http://msdn.microsoft.com/en-us/library/bb166492.aspx
Does anyone know if an Update of the UI can be done by demand?
Any hints are greatly appreciated.
I finally got this working. The main thing is the implementation of a derived class of OleMenuCommand that implements a new constructor with a Predicate. This predicate is used to check if a new command is a match within the DynamicItemStart button.
public class DynamicItemMenuCommand : OleMenuCommand
{
private Predicate<int> matches;
public DynamicItemMenuCommand(CommandID rootId, Predicate<int> matches, EventHandler invokeHandler, EventHandler beforeQueryStatusHandler)
: base(invokeHandler, null, beforeQueryStatusHandler, rootId)
{
if (matches == null)
{
throw new ArgumentNullException("Matches predicate cannot be null.");
}
this.matches = matches;
}
public override bool DynamicItemMatch(int cmdId)
{
if (this.matches(cmdId))
{
this.MatchedCommandId = cmdId;
return true;
}
this.MatchedCommandId = 0;
return false;
}
}
The above class should be used when adding the commands on execution time. Here's the code that creates the commands
public class ListMenu
{
private int _baselistID = (int)PkgCmdIDList.cmdidMRUList;
private List<IVsDataExplorerConnection> _connectionsList;
public ListMenu(ref OleMenuCommandService mcs)
{
InitMRUMenu(ref mcs);
}
internal void InitMRUMenu(ref OleMenuCommandService mcs)
{
if (mcs != null)
{
//_baselistID has the guid value of the DynamicStartItem
CommandID dynamicItemRootId = new CommandID(GuidList.guidIDEToolbarCmdSet, _baselistID);
DynamicItemMenuCommand dynamicMenuCommand = new DynamicItemMenuCommand(dynamicItemRootId, isValidDynamicItem, OnInvokedDynamicItem, OnBeforeQueryStatusDynamicItem);
mcs.AddCommand(dynamicMenuCommand);
}
}
private bool IsValidDynamicItem(int commandId)
{
return ((commandId - _baselistID) < connectionsCount); // here is the place to put the criteria to add a new command to the dynamic button
}
private void OnInvokedDynamicItem(object sender, EventArgs args)
{
DynamicItemMenuCommand invokedCommand = (DynamicItemMenuCommand)sender;
if (null != invokedCommand)
{
.....
}
}
private void OnBeforeQueryStatusDynamicItem(object sender, EventArgs args)
{
DynamicItemMenuCommand matchedCommand = (DynamicItemMenuCommand)sender;
bool isRootItem = (matchedCommand.MatchedCommandId == 0);
matchedCommand.Enabled = true;
matchedCommand.Visible = true;
int indexForDisplay = (isRootItem ? 0 : (matchedCommand.MatchedCommandId - _baselistID));
matchedCommand.Text = "Text for the command";
matchedCommand.MatchedCommandId = 0;
}
}
I had to review a lot of documentation since it was not very clear how the commands can be added on execution time. So I hope this save some time whoever has to implement anything similar.
The missing piece for me was figuring out how to control the addition of new items.
It took me some time to figure out that the matches predicate (the IsValidDynamicItem method in the sample) controls how many items get added - as long as it returns true, the OnBeforeQueryStatusDynamicItem gets invoked and can set the details (Enabled/Visible/Checked/Text etc.) of the match to be added to the menu.
I wish to populate a drop down box with each possible SeriesChartType so that my users may choose an appropriate chart type.
How can I iterate through the SeriesChartType collection (it's in the namespace System.Web.Ui.DataVisualization.Charting) and return each possible option so I can add it to the drop down box?
Thanks.
This worked for me in VB - I had to instantiate a new instance of the SeriesChartType which allowed me to use the [Enum].GetNames Method.
I was then able to add them to the drop down box as shown:
Dim z As New SeriesChartType
For Each charttype As String In [Enum].GetNames(z.GetType)
Dim itm As New ListItem
itm.Text = charttype
ddl_ChartType.Items.Add(itm)
Next
Thanks to everyone for your answers. mrK has a great C alternative to this VB code.
foreach (ChartType in Enum.GetValues(typeof(System.Web.UI.DataVisualization.Charting))
{
//Add an option the the dropdown menu
// Convert.ToString(ChartType) <- Text of Item
// Convert.ToInt32(ChartType) <- Value of Item
}
If this isn't what you're looking for, let me know.
You could bind data in the DataBind event handler:
public override void DataBind()
{
ddlChartType.DataSource =
Enum.GetValues(typeof(SeriesChartType))
.Cast<SeriesChartType>()
.Select(i => new ListItem(i.ToString(), i.ToString()));
ddlChartType.DataBind();
}
and then retrieve the selected value in the SelectedIndexChanged event handler like this:
protected void ddlChartType_SelectedIndexChanged(object sender, EventArgs e)
{
// holds the selected value
SeriesChartType selectedValue =
(SeriesChartType)Enum.Parse(typeof(SeriesChartType),
((DropDownList)sender).SelectedValue);
}
Here's a generic function:
// ---- EnumToListBox ------------------------------------
//
// Fills List controls (ListBox, DropDownList) with the text
// and value of enums
//
// Usage: EnumToListBox(typeof(MyEnum), ListBox1);
static public void EnumToListBox(Type EnumType, ListControl TheListBox)
{
Array Values = System.Enum.GetValues(EnumType);
foreach (int Value in Values)
{
string Display = Enum.GetName(EnumType, Value);
ListItem Item = new ListItem(Display, Value.ToString());
TheListBox.Items.Add(Item);
}
}
Can I somehow find out what was the change in the textfield? I would want to compare the old text with the new text ... the problem is, that I have multiple textAreas in a tab-editor, and all the textAreas are watched by one eventListener. I want to get a value calculated by the next formula:
globalChangeCount += thisTextArea.currentCharacterCount - thisTextArea.oldtCharacterCount
where the globalChangeCount is a value modified by all changes in any of the textAreas.
I am searching for these values through the event variable, but can't seam to find the old text of the textArea.
This may or may not be what you're looking to do:
package
{
import mx.controls.TextArea;
public class CountingTextArea extends TextArea
{
public var staleText : String = "";
[Bindable("textChanged")]
[NonCommittingChangeEvent("change")]
public function get charDiff() : int
{
var diff : int = staleText.length - text.length;
staleText = text;
return diff;
}
public function CountingTextArea()
{
super();
}
}
}
I made it so that you can use it as a source for binding. Instead of subscribing to the event on each TextArea, you can use:
function addWatchers():void
{
ChangeWatcher.watch(countingTextArea1, ["charDiff"], charDiffChangeHandler );
...
ChangeWatcher.watch(countingTextArea5, ["charDiff"], charDiffChangeHandler );
}
With the event handler somewhere too:
function charDiffChangeHandler( event : PropertyChangeEvent ) : void
{
trace(event.currentTarget.charDiff);
// or
trace(event.newValue);
}
You can use event.currentTarget to get a reference to the TextArea that fired the event, and use the focusIn event to execute a function to populate a variable with the old text value.
Maybe you should just subclass the TextArea and create an oldText field variable you update internally after all the external listeners have been notified.