i have this enum called ScoreType.
public enum ScoreType {
Ones, Twos, Threes, Fours, Fives, Sixes,
SubTotal, BonusFor63Plus, SectionATotal,
ThreeOfAKind, FourOfAKind, FullHouse,
SmallStraight, LargeStraight, Chance, Yahtzee,
YahtzeeBonus, SectionBTotal, GrandTotal
}
I would like to in the EnableScoreButton method to enable the specified button corresponding to the ScoreType parameter of 'combo'.
public void EnableScoreButton(ScoreType combo) {
//SOMTHING.Enabled = true;
}
Could you please show me how to do this?
Related
Using Build 21.210.0030
I’m a bit of a ‘noob’ to Acumatica dev and I have a question concerning toolbar buttons on a Generic Inquiry (GI) with the intention of performing a Mass Action. The following PXAction works on the Vendor form (../Main?ScreenId=AP303000&AcctCD=AASERVICES):
public class VendorMaint_Extension : PXGraphExtension<VendorMaint>
{
public SelectFrom<PX.Objects.CR.BAccount>.View suppliers;
#region buttons
public PXAction<PX.Objects.CR.BAccount> myButton;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Verify Now", IsDirty = true)]
public virtual IEnumerable MyButton(PXAdapter adapter)
{
BAccount supplier = suppliers.Current;
PX.Objects.CR.BAccountExt bAccountExt = PXCache<BAccount>.GetExtension<PX.Objects.CR.BAccountExt>(supplier);
// do my stuff...
//...
//...
return adapter.Get();
}
#endregion buttons
//...
//...
My GI is a filtered copy of AP-Vendors (AP3030PL) but I can’t get my button to display in the list of available Mass Actions. I’ve tried adding the following in the class (above)
public override void Initialize()
{
base.Initialize();
myButton.IsMass = true;
Base.action.AddMenuAction(this.myButton);
}
and I’ve tried many variations of this Initialize method but none seem to make a difference. I've also tried to implement the answers provided in these previous questions (to no avail):
How to add action button in Inquiry page? and
Add Custom action to GI Mass Actions dropdown
I think part of my issue is that I don't fully understand whether to use BAccount, VendorR and/or Vendor yet.
I fully accept that I might be doing it all wrong so any and all help will be gratefully appreciated.
Thanks
Turns out it was relatively straight-forward, very similar to the way processing forms work. I had to change the button from a PXButton to a PXProcessButton in my VendorMaint_Extension class and move the code (that does the actual work) into a static method used by the PXLongOperation e.g.
```
[PXProcessButton(CommitChanges = true)]
[PXUIField(DisplayName = "Verify Now", IsDirty = true)]
public virtual IEnumerable MyButton(PXAdapter adapter)
{
bool isMassProcess = adapter.MassProcess;
List<BAccount> vendorList = new List<BAccount>();
foreach (BAccount bAcc in adapter.Get<BAccount>())
{
PX.Objects.CR.BAccountExt bAccountExt = PXCache<BAccount>.GetExtension<PX.Objects.CR.BAccountExt>(bAcc);
if (bAccountExt.UsrIsSomething == true)
{
vendorList.Add(bAcc);
}
}
// trigger the Save action to save changes in the database.
Base.Save.Press();
PXLongOperation.StartOperation(this, delegate ()
{
DoMyStuff(vendorList, isMassProcess);
});
return vendorList;
}
```
In app I'm bulding I used data model presented by James_D here:
Applying MVC With JavaFx
I just can find a way to bind labels text to property of object held in DataModel
Data is structured like this:
model class Student
//partial class
public class Student {
private final StringProperty displayName = new SimpleStringProperty();
public final StringProperty displayNameProperty(){
return this.displayName;
}
public Student(){
}
public final String getDisplayName() {
return this.displayNameProperty().get();
}
public final void setDisplayName(String displayName) {
this.displayNameProperty().set(displayName);
}
}
Student instaces are held by StudentDataModel class
public class StudentDataModel {
// complete student list
private final ObservableList<Student> studentList = FXCollections.observableArrayList();
private final ObjectProperty<Student> selectedStudent = new SimpleObjectProperty<>(new Student());
public final Student getSelectedStudent() {
return selectedStudent.get();
}
public final ObjectProperty<Student> selectedStudentProperty() {
return selectedStudent;
}
public final void setSelectedStudent(Student student) {
selectedStudent.set(student);
}
}
StudentList is displayed by Table View, there is change listener that sets selectedStudent like this:
public class TableViewController {
public void initModel(StudentDataModel studentDM) {
// ensure model is set once
if (this.studentDM != null) {
throw new IllegalStateException("StudentDataModel can only be initialized once");
}
this.studentDM = studentDM;
tableView.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> {
if (newSelection != null) {
studentDM.setSelectedStudent(newSelection);
}
});
}}
There is another controller ActionsBarController that has label to display selected student (this seems redundant, but there is option for selecting multiple objects to perform bulk operations).
StudentDataModel is initialized properly (I can see it in debuger) but below doesn't do anything:
chosenStudentLabel.textProperty().bind(studentDM.getSelectedStudent().displayNameProperty());
//this shows class name with instance number changing correctly
chosenStudentLabel.textProperty().bind(studentDM.selectedStudentProperty().asString());
I could inject ActionsBarController to TableViewController and change label text from change Listener there, but this seems counter productive with data model.
What am I doing wrong?
Your code doesn't work, because you call (and evaluate) getSelectedStudent() at the time the binding is created (i.e. when you initialize the model). As a consequence, you only bind to the displayName property of the student that is selected at that time. (If nothing is selected, you'll get a NullPointerException.) The binding will only change if that initially-selected student's display name changes; it won't change if the selection changes.
You need a binding that unbinds from the old selected student's display name, and binds to the new selected student's display name, when the selected student changes. One way to do this is:
chosenStudentLabel.textProperty().bind(new StringBinding() {
{
studentDM.selectedStudentProperty().addListener((obs, oldStudent, newStudent) -> {
if (oldStudent != null) {
unbind(oldStudent.displayNameProperty());
}
if (newStudent != null) {
bind(newStudent.displayNameProperty());
}
invalidate();
});
}
#Override
protected String computeValue() {
if (studentDM.getSelectedStudent() == null) {
return "" ;
}
return studentDM.getSelectedStudent().getDisplayName();
}
});
Note that there is also a "built-in" way to do this, but it's a bit unsatisfactory (in my opinion) for a couple of reasons. Firstly, it relies on specifying the name of the "nested property" as a String, using reflection to access it. This is undesirable because it has no way to check the property exists at compile time, it requires opening the module for access, and it is less good performance-wise. Secondly, it gives spurious warnings if one of the properties in the "chain" is null (e.g. in this case if the selected student is null, which is will be initially), even though this is a supported case according to the documentation. However, it is significantly less code:
chosenStudentLabel.textProperty().bind(
Bindings.selectString(studentDM.selectedStudentProperty(), "displayName")
);
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.
When registering a custom language service extension, Visual Studio creates a new options entry for the language within the Text Editor node (in the Visual Studio options dialog). Beneath that node two default nodes are created named General and Tabs, whereby the General tab contains statement completion and display settings...
In the Dispay group there are three options; one of them is the Navigation Bar checkbox (which shows/hides the editor´s navigation bar). For my custom language service, this option is disabled. Of course, it´s not implemented yet.
I would like to know, what I have to do, to provide a navigation bar for my custom editor... I guess that there is a certain interface I have to implement in the editor´s factory, or the language service package must export a certain MEF component, or, or, ...
Jon Senchyna´s answer guided me into the right direction. The OnSynchronizeDropdowns method gets never called (the SDK documentation is just wrong in that case). What did the final trick was to override at least GetComboAttributes, GetEntryAttributes and GetEntryText to get text-only items for both combo boxes...
[ComVisible(true)]
public sealed class CustomTypeAndMemberDropdownBars : TypeAndMemberDropdownBars
{
private readonly IList<string> declarations;
private readonly IList<string> members;
public CustomTypeAndMemberDropdownBars(
LanguageService languageService,
IVsTextView view)
: base(languageService)
{
// TODO: initialize declarations and members from the given text view...
this.declarations = ...
this.members = ...
}
private enum ComboIndex
{
Types = 0,
Members = 1
}
public override int GetComboAttributes(
int combo,
out uint entries,
out uint entryType,
out IntPtr imageList)
{
entries = 0;
imageList = IntPtr.Zero;
entryType = (uint)DROPDOWNENTRYTYPE.ENTRY_TEXT;
var comboType = (ComboIndex)combo;
switch (comboType)
{
case ComboIndex.Types:
entries = (uint)this.declarations.Count();
break;
case ComboIndex.Members:
entries = (uint)this.members.Count();
break;
}
return VSConstants.S_OK;
}
public override int GetEntryAttributes(
int combo,
int entry,
out uint fontAttrs)
{
fontAttrs = (uint)DROPDOWNFONTATTR.FONTATTR_PLAIN;
return VSConstants.S_OK;
}
public override int GetEntryText(
int combo,
int entry,
out string text)
{
text = null;
var comboType = (ComboIndex)combo;
switch (comboType)
{
case ComboIndex.Types:
text = this.declarations[entry];
break;
case ComboIndex.Members:
text = this.members[entry];
break;
}
return VSConstants.S_OK;
}
public override bool OnSynchronizeDropdowns(
LanguageService languageService,
IVsTextView textView,
int line,
int col,
ArrayList dropDownTypes,
ArrayList dropDownMembers,
ref int selectedType,
ref int selectedMember)
{
return false;
}
}
I believe the following steps should be what you need:
In your Package class, set the ShowDropDownOptions property to true in the ProvideLanguageService attribute
Create a class that implements TypeAndMemberDropdownBars
In your LanguageService class, implement the CreateDropDownHelper function and have it return an instance of your TypeAndMemberDropdownBars
I have an ASPxGridView from DevExpress fed with data from ObjectDataSource. My data row objects expose properties such ParameterName, ParameterType and ParameterValue.
//Properties, constructor and private fields code omitted for clarity
public class InputParameterDescription
{
public string ParameterName;
public Type ParameterType;
public int ParameterPrecision;
public string ParameterDescription;
}
ParameterValue is always an object of type indicated by ParameterType property. In fact, I use few types – Int32, Double, String or Boolean. When I display values in a grid and user clicks “Edit” a ParameterValue is always edited with TextBox. Is it possible to change editor for this column according to ParameterType? I want my users to use SpinEdit for integers, checkbox for Boolean, etc.
In fact, this is the way people have been working with DevExpress Delphi grids - TdxGrid and TcxGrid (OnGetProperties event). I have asked this question in DevExpress forum, but haven’t got any answer :(
You could create a template on that column that would do the switch for you. Something like:
public class SwitchTemplate : ITemplate
{
public void Instantiate(Control container)
{
GridViewDataItemTemplateContainer cnt = (GridViewDataItemTemplateContainer) container;
switch( GetStringParameterTypeFromDataItem(cnt.DataItem) )
{
case "Int32":
container.Controls.Add( new ASPxSpinEdit() { ... } );
break;
case "DateTime":
container.Controls.Add( new ASPxDateEdit() { ... } );
break;
case "String":
container.Controls.Add( new ASPxTextBox() { ... } );
break;
...
}
}
}
Then you just need to specify this template as the EditItemTemplate of the column:
myGrid.Columns["MyColumnName"].EditItemTemplate = new SwitchTemplate()