I have created a grid view of Leavemaster table and leaveApplication table.
There is field LeaveId in LeaveMaster and foreign key in LeaveApplication table.
I want to, when I select leaveId in LeaveAppliation table, automatically have related fields like LeaveName be filled according to LeaveId.
If you only want to show the leaveName use a display method defined on the LeaveApplicationTable:
display EmplName leaveName()
{
return LeaveMasterTable::find(this.LeaveId).Name;
}
If you have more fields to show consider using outer-join.
In the LeaveApplicationTable form add the LeaveMasterTable as a secondary datasource and use outer-join as the joinMode (Allow-Edit: false).
Add a modified method to the LeaveId field on theLeaveApplicationTable datasource:
public void modified()
{
super();
leaveMasterTable.data(LeaveMasterTable::find(leaveApplicationTable.LeaveId));
leaveMasterTable_ds.refresh()
}
Also change the validateWrite and write methods of the LeaveMasterTable datasource to not change any data:
public boolean validateWrite()
{
return true;
}
public void write()
{
//super();
}
Related
I want to initialize a value of an edit method inside the init method of form, i wrote this:
[Form]
public class foo extends FormRun
{
str paymTermId;
public void init()
{
CustTable custTable = CustTable::find("DE-001");
paymTermId = custTable.paymTermId;
super();
}
edit str edtpaymTermId(boolean set, str _paymTermId)
{
if (set)
{
paymTermId= _paymTermId;
}
return paymTermId ;
}
}
But when i open the form the control remains empty.
any suggestions?
I tried to reproduce the issue, but was not successful. For me, when opening the form, the control shows a value.
A possible reason why it is not working for you could be that you open the form in the wrong company. In your code, you retrieve the value to display in the control from the payment term of customer DE-001. This customer exists in company USMF in the Contoso demo data and has payment term Net10. If the form is opened in this company, the value is shown in the control. If you are in another company (e.g. DAT), no value is shown.
I see 2 things that are wrong:
You are setting the value BEFORE super(). It should be after.
You SHOULDN'T initialize the value via field, you should do it calling edit method. Edit methods have a boolean SET parameter which can simulate a call for setting a value.
Is there a way to display an info log when selecting a certain record in a dropdown menu/based on a field value?
For example:
When creating a new Quotation, if I select a customer which is bankrupt (so the value on the field bankrupt is true for that customer.) I want to show a info dialog: "Bankrupt!" I want to show this before the record is being created, at the moment it is being selected.
In your form find the field you want (form layout, no datasource), override Modified method an put your code before super();
To get the value use: this.text(); Here you can get the select value before insert.
Code example:
public boolean modified()
{
boolean ret;
CustTable custTable = CustTable::find(this.text());
if (custTable.Bankrupt == NoYes::Yes)
info("Bankrupt!");
ret = super();
return ret;
}
I have a form with 2 fields, the 1st is filled with a lookup and the 2nd (not editable, just a Description of the 1st) is filled with a "display" method in the form.
public display Name displaySalesChannelName()
{
return SalesChannelTable::find(SalesChannelFilter.valueStr()).Description;
}
Seems to work fine, but only shows the value when the field is clicked.
How can I synchronize this 2 fields?
You can override method modified of the 1st control (with the lookup) and call method update of the 2nd control from there, e.g. if the name of the 2nd control is SalesChannelName and its AutoDeclaration property has been set to Yes, then:
public boolean modified()
{
boolean ret = super();
SalesChannelName.update();
return ret;
}
But then there's not much sense in using a display method here. You can just as well clear the DataMethod property of the 2nd control, and the modified method above can be rewritten as follows:
public boolean modified()
{
boolean ret = super();
SalesChannelName.text(SalesChannelTable::find(this.valueStr()).Description);
return ret;
}
you should try to put the display method on table level, your field's properties in the form must have the datasource Table name as datasource and your method's name as data method
I have a ViewModel that contains a (Person)Patient property. In my View, I bind to some of the properties of Patient, say, Name and Age.
The problem is: if I change Patient, nothing happens in my view, unless I explicitly notify of each property change (I am using Caliburn.Micro thus the PropertyChangedBaseand NotifyOfPropertyChange stuff):
public class PersonViewModel : PropertyChangedBase {
Person _patient;
public Person Patient {
get { return _patient; }
set {
_patient = value;
NotifyOfPropertyChange(() => Patient); // this doesn't update the view
NotifyOfPropertyChange(() => Name); // this updates, but would I need one line for each property??
}
}
}
The broader application context is this: I have a PersonManager screen, with three regions, each with their view and viewmodel: a list of persons, the information of a single person, and the list of medical procedures associated with each person.
I am almost sure I am missing something here. I would like to select a person in the person list, and then the regions showing person data and person procedures would update via binding, without having to manually notify each property change of the newly selected person.
I have solved the problem using a feature of PropertyChanged event, which is using null as a parameter:
The PropertyChanged event can indicate all properties on the object
have changed by using either null or String.Empty as the property name
in the PropertyChangedEventArgs.
Then, I solved my problem with:
public Paciente Paciente {
get { return _paciente; }
set {
_paciente = value;
NotifyOfPropertyChange(null);
}
}
and it worked!
I have a question regarding a data binding(of multiple properties) for custom DataGridViewColumn.
Here is a schema of what controls that I have, and I need to make it bindable with DataGridView datasource. Any ideas or a link to an article discussing the matter?
Controls
Graph Control(custom): Displayed in
the custrom DataGridView column. Has
properties like "Start Date",
"EndDate", Windows Chart control,
which is itself, bindable, etc.
Custom cell(DataGridViewCustomCell inherits
from DataGridViewCell) that holds
the Graph control and processes some
events(OnEnter event, for example,
passes the focus to the custom Graph
column for drag-n-drop type of
events, etc.)
Custom column(DataGridViewCustomColumn
inherits from DataGridViewColumn)
that defined the cell template type:
CellTemplate = new
DataGridViewCustomCell(); and also a
primary choice for data binding
Data Structure:
Main table to be displayed in other DataGridView Columns
Graph table - related to the Main table via parent-child relationship. Holds graph data
Chart table related to the graph table via parent-child relationship. Holds data for the win-form chart, which is a part of my Graph control.
So far I cannot even bind data from the Graph table to by Graph control or Graph-holding Column/Cell.
Thank you for your answer. My data sources is not a SQL data source, and as a matter of fact I was talking about datagridview for win-forms(I'm not sure that was clear).
As I did not get the reply on any of the forums I was asking the question, I figured, I would outline a solution I came up with, for those who may have a similar problem and for possible critique. :-)
(steps 1-2 are also explained in the famous MS example)
1. Create your own classes that inherit from DataGridViewColumn and DataGridViewCell, setup the column template;
2. Create your "CustomEdit" control
In the data item, whatever that is, a DataRow, or a List item, add a read-only property, that return the object itself. This property is bound to the custom column.
Custom Cell:
public partial class MyCell : DataGridViewCell
{
protected override void Paint(...)
{...} // draws control
// receives data item as a value
// in my case I have to custom-draw entire control in this fnc.
public override void InitializeEditingControl(...)
{...} // initialize control editing
// override some other properties
public override Type EditType {
get{
return typeof(MyEditControl);
}
}
public override Type ValueType{
get{
return typeof(MyItem);
}
}
}
Custom Column:
public partial class MyColumn : DataGridViewColumn
{
public MyColumn(){ ...
CellTemplate = new MyCell();
}
}
Edit Control:
public partial class MyEditControl : UserControl, IDataGridViewEditingControl
{... // implements IDataGridViewEditingControl
// value is our data item
}
Data Item, the data sources becomes List<MyItem>
public class MyItem:Object{
...
[XmlIgnore] // I need it because I do serialization
public MyItem Self {
get {
return this;
}
}
}
See my question Here
It's easy to do, you just don't use the IDE to do it, you do it all in code. It's a lot of work, but it's not that difficult if you know what your doing. I went from knowing nothing to being able to do it in less than a day so I'm sure you'll be able to do it.
Edit: you can also use a Join in the sql that populates the datagridview