Reputation: 772
I have created DevExpress XAF Blazor application.
I have four tables(pages)
The first one is Category related by a one-to-many with AssignedContractorCategory table
-oid string
-Title string
private string _Title;
public string Title
{
get { return _Title; }
set { SetPropertyValue(nameof(Title), ref _Title, value); }
}
[DevExpress.Xpo.Association("Category-AssignedContractorCategory")]
public XPCollection<AssignedContractorCategory> AssignedContractorCategory
{
get
{
return GetCollection<AssignedContractorCategory>(nameof(AssignedContractorCategory));
}
}
The second one is Contractor related by a one-to-many with AssignedContractorCategory table
-oid string
-Title string
private string _Title;
public string Title
{
get { return _Title; }
set { SetPropertyValue(nameof(Title), ref _Title, value); }
}
[DevExpress.Xpo.Association("Contractor-AssignedContractorCategory")]
public XPCollection<AssignedContractorCategory> AssignedContractorCategory
{
get
{
return GetCollection<AssignedContractorCategory>(nameof(AssignedContractorCategory));
}
}
The third one is AssignedContractorCategory related by a one-to-many with Bill table
-oid string
-FKCategory string
-FKContractor string
private Category _Category;
[Association("Category-AssignedContractorCategory")]
public Category Category
{
get { return _Category; }
set { SetPropertyValue(nameof(Category), ref _Category, value); }
}
private Contractor _Contractor;
[Association("Contractor-AssignedContractorCategory")]
public Contractor Contractor
{
get { return _Contractor; }
set { SetPropertyValue(nameof(Contractor), ref _Contractor, value); }
}
The fourth one is Bill
-oid string
-FKAssignedContractorCategory string
-Amount double
private Category _Category;
public Category Category
{
get { return _Category; }
set { SetPropertyValue(nameof(Category), ref _Category, value); }
}
private Contractor _Contractor;
public Contractor Contractor
{
get { return _Contractor; }
set { SetPropertyValue(nameof(Contractor), ref _Contractor, value); }
}
private double _Amount;
public double Amount
{
get { return _Amount; }
set { SetPropertyValue(nameof(Amount), ref _Amount, value); }
}
On Bill page I want to show :
Category (Lookup List Views) and after I chose one category it shows only Contractor (Lookup List Views) that are related on table AssignedContractorCategory
Please note that I am a beginner.
Upvotes: 1
Views: 1092
Reputation: 840
Step 1: On your Bill
class, decorate the Category
-property with the ImmediatePostData
attribute. It will ensure that the setter will get called immediately after every change on the UI:
[ImmediatePostData]
public Category Category
Step 2: On the Bill
class, add the DataSourceProperty
-attribute to your Contractor
property, and then implement a corresponding property which always returns the correct selection of Contractors. Note that I decorate the new ContractorSelection
-property with [Browsable(false)]
so that it's completely invisible on the XAF UI:
private Contractor _Contractor;
[DataSourceProperty(nameof(ContractorSelection))]
public Contractor Contractor
{
get { return _Contractor; }
set { SetPropertyValue(nameof(Contractor), ref _Contractor, value); }
}
[Browsable(false)]
public IList<Contractor> ContractorSelection
{
get
{
return Category?.AssignedContractorCategory.Select(i => i.Contractor).Distinct().ToList();
}
}
Step 3: The problem now is that XAF does not automatically update its internal cache of the ContractorSelection-collection when you change the Category
. For this to work, you need to change the setter of your Category
-property and tell XAF than the Contractor
property has also changed:
[ImmediatePostData]
public Category Category
{
get { return _Category; }
set
{
SetPropertyValue(nameof(Category), ref _Category, value);
if (!IsLoading)
{
OnChanged(nameof(Contractor));
}
}
}
I tested this, and it works fine in XAF Blazor.
Alternative method:
If you prefer your objects to be filtered by the DB (ideal if you have a large collection of contractors), you can use the DataSourceCriteria
-attribute instead, and then remove the ContractorSelection
-property from my initial solution. All the other code remains the same:
private Contractor _Contractor;
[DataSourceCriteria("AssignedContractorCategory[Category = '@This.Category'].Count > 0")]
public Contractor Contractor
{
get { return _Contractor; }
set { SetPropertyValue(nameof(Contractor), ref _Contractor, value); }
}
Additional Info:
DataSourceProperty
-attribute on how you can specify the appropriate behavior in case the datasource is null.Category
-setter to enforce other constraints, such as setting the Contractor
to null in case the currently selected Contractor
is not part of the selected category. The more interdependent properties you have, the more complex this gets.AssignedContractorCategory
class is only used as a pure link between Contractor
and Category
(without additional properties), then you may want to consider using XPO's integrated many-to-many associationsUpvotes: 2