Sort Alphabetic ObservableCollection binded to ListBox - c#

I wrote a little Function for scanning Files with Virus Total using the API. Its working great but the Scan Result is not Sorted Alphabetic.
Here is my Code:
public void init(FileReport _scanResult) {
try {
if (_scanResult.ResponseCode == ReportResponseCode.Present) {
foreach (ScanEngine scan in _scanResult.Scans) {
if (scan.Detected == true) {
howMany++;
_scanResultItems.Add(new ScanResultItems {
AvName = scan.Name,
AvResult = new Uri("/Images/inWatch.avNOT.png", UriKind.RelativeOrAbsolute),
AvStatus = "BEDROHUNG!"
});
Width = 390;
}
else {
_scanResultItems.Add(new ScanResultItems {
AvName = scan.Name,
AvResult = new Uri("/Images/inWatch.avOK.png", UriKind.RelativeOrAbsolute),
AvStatus = "OK"
});
}
}
lstScanResults.ItemsSource = _scanResultItems.OrderBy(item => item.AvName).ToList();
}
}
catch(Exception ex) {
GeneralSettings.LogException(ex);
}
Thanks for your Answers!

You could order items inside your result set by using System.Linq; OrderBy() method, like this:
_scanResultItems = _scanResultItems.OrderBy(item => item.Name).ToList();

Related

Performance issue when performing operations on entity objects

Im facing performance issue in below code in multiple foreach loops. First im getting a list of ReturnDetails and then based on detail id get the HandlingInfo object. Then based on value of action, update the ReturnsDetail Object again.
It take more than a minute for loading 3000 records of ReturnsDetail. While debugging locally, it runs for infinite amount of time.
Please let me know in anyway i can refactor this code .
Thanks for your help.
lstReturnsDetail = dcReturnsService.GetReturnDetailsInfo(header_id);
List<HandlingInfo> lstHandlingInfo = null;
foreach (ReturnsDetail oReturnsDetail in lstReturnsDetail)
{
using (DCReturns_Entities entities = new DCReturns_Entities())
{
lstHandlingInfo = entities.HandlingInfoes.Where(f => f.detail_id == oReturnsDetail.id).ToList();
if(lstHandlingInfo != null)
{
foreach (HandlingInfo oHandlingInfo in lstHandlingInfo)
{
if (oHandlingInfo.action == "DST")
{
oReturnsDetail.destroy += Convert.ToInt32(oHandlingInfo.qty);
}
else if (oHandlingInfo.action == "SHP")
{
oReturnsDetail.to_shop += Convert.ToInt32(oHandlingInfo.qty);
}
else if (oHandlingInfo.action == "RBX")
{
oReturnsDetail.in_stock += Convert.ToInt32(oHandlingInfo.qty);
}
}
}
}
oReturnsDetail.received_qty = oReturnsDetail.destroy + oReturnsDetail.to_shop + oReturnsDetail.in_stock;
}
dgReturnsDetail.DataSource = lstReturnsDetail.OrderByDescending(g => g.id).ToList();
Session[DCReturnsConstants.Returns_Detail_Entity] = lstReturnsDetail;
dgReturnsDetail.DataBind();
this is su-do code! but you should get the jist.
//modify this to return all of them into mem, and then filter on this...
//if it can not be done here then do below..
var lstReturnsDetail = dcReturnsService.GetReturnDetailsInfo(header_id);
//then create a list here which fetches all,
List<[type]> somelist
List<int> listId = lstReturnsDetail.select(x=>x.id).tolist();
using (var db = new DCReturns_Entities())
{
somelist = db.HandlingInfoes.Where(f => listId.Contains( f.detail_id)).ToList();
}
foreach (ReturnsDetail oReturnsDetail in lstReturnsDetail)
{
//performance issue is here
//using (DCReturns_Entities entities = new DCReturns_Entities())
//{
// lstHandlingInfo = entities.HandlingInfoes.Where(f => f.detail_id == oReturnsDetail.id).ToList();
//}
//insead fetach all before, into mem and filter from that list.
var lstHandlingInfo = somelist.Where(f => f.detail_id == oReturnsDetail.id).ToList();
//code ommited for reaablity
}
//code ommited for reaablity

How to speed up workflow with database .Net

I have simple controller that return list of products.It is take about 5-7sec to return the data for the first time,and then 50-80ms ,but only if i run it immediately(10-30sec) after first one ,if i will run it after 2-3min it will be again 5-7s.
I dont store this list in cache,sow i cant understand why only first time it takes 5sec,and then 50ms.
Important:test that i have made is not on localhost,it is on the production server.On localhost it takes 50ms
How can i speed up?
Do i need to make any change in my code? Or IIS?
My code
public List<PackageModel> GetPromotionOrDefaultPackageList(string domain)
{
List<DBProduct> DBPackageList = new List<DBProduct>();
List<PackageModel> BllPackageList = new List<PackageModel>();
try
{
using (CglDomainEntities _entities = new CglDomainEntities())
{
DBPackageList = _entities.DBProducts
.Where(x =>
x.ProductGroup.Equals(domain + "-package")
&& x.IsPromotionProduct == true)
.ToList();
if (DBPackageList.Count == 0)
{
DBPackageList = _entities.DBProducts
.Where(x =>
x.ProductGroup.Equals(domain + "-package")
&& x.IsBasicProduct == true)
.ToList();
}
}
PackageModel bllPackage = new PackageModel();
foreach (DBProduct dbProduct in DBPackageList)
{
bllPackage = new PackageModel();
bllPackage.Id = dbProduct.Id;
bllPackage.ProductId = dbProduct.ProductId;
bllPackage.IsPromotionProduct = dbProduct.IsPromotionProduct.HasValue ? dbProduct.IsPromotionProduct.Value : false;
bllPackage.ProductName = dbProduct.ProductName;
bllPackage.ProductDescription = dbProduct.ProductDescription;
bllPackage.Price = dbProduct.Price;
bllPackage.Currency = dbProduct.Currency;
bllPackage.CampaignId = dbProduct.CampaignId;
bllPackage.PathToProductImage = dbProduct.PathToProductImage;
bllPackage.PathToProductPromotionImage = dbProduct.PathToProductPromotionImage;
bllPackage.PathToProductInfo = dbProduct.PathToProductInfo;
bllPackage.CssClass = dbProduct.CssClass;
BllPackageList.Add(bllPackage);
}
return BllPackageList;
}
catch (Exception ex)
{
Logger.Error(ex.Message);
return BllPackageList;
}
}

c# using advanced datagridview (ADGV) filter without BindingSource

I am using the advanced DataGridView (ADGV) found here to add filtering capabilities to my application.
The code for filtering or sorting is mentioned as:
private void advancedDataGridView1_SortStringChanged(object sender, EventArgs e)
{
this.stockHistoryBindingSource.Sort = advancedDataGridView1.SortString;
}
private void advancedDataGridView1_FilterStringChanged(object sender, EventArgs e)
{
this.stockHistoryBindingSource.Filter = advancedDataGridView1.FilterString;
}
But I can't use this because in my project I am reading an XML file and binding it to my ADGV with this code:
void QueryFoos()
{
IEnumerable<FooViewData> query =
from foo in XmlFiles.FOO.Root.Descendants("foo")
select new FooViewData
{
ID = Convert.ToInt32(foo.Attribute("id").Value),
Num = Convert.ToInt32(foo.Attribute("num").Value),
...
};
advancedDataGridView1.DataSource = query.OrderBy(n => n.ID).ThenBy(r => r.Num).ToList();
}
I tried a code like this but I am not surprised that it is throwing exception in my face:
BindingSource x = (BindingSource)this.advancedDataGridView1.DataSource;
x.Filter = advancedDataGridView1.FilterString;
this.advancedDataGridView1.DataSource = x;
Is there some work around to use the filtering and sorting of the ADGV ?
As it turns out I had this same problem today and was looking for solutions. Basically the problem is that ADGV was written to be used with a DataTable and not a list of objects.
This solution works for me however your mileage may vary.
What I ended up doing was using dynamic linq to perform the filter on the list of objects myself. The hack part was me converting the filter string that ADGV produces and converting it to a string that dynamic linq expects.
We start with some data. I have a class named DataPointGridViewModel that looks like this:
public class DataPointGridViewModel
{
public int DataPointId { get; set; }
public string Description { get; set; }
public bool InAlarm { get; set; }
public DateTime LastUpdate { get; set; }
public double ScalingMultiplier { get; set; }
public decimal Price { get; set; }
}
The data could be anything. This is the data that you will be filtering on in the grid. Obviously you will have your own data class. You need to replace this DataPointGridViewModel clas with your own model/data object.
Now, here is the code example code you need to add. I have also got a sample project on github here: I have a working version of this code on github: here
Here is the code you need to add:
List<DataPointGridViewModel> m_dataGridBindingList = null;
List<DataPointGridViewModel> m_filteredList = null;
private void dataGridView2_FilterStringChanged(object sender, Zuby.ADGV.AdvancedDataGridView.FilterEventArgs e)
{
try
{
if ( string.IsNullOrEmpty(dataGridView2.FilterString) == true )
{
m_filteredList = m_dataGridBindingList;
dataGridView2.DataSource = m_dataGridBindingList;
}
else
{
var listfilter = FilterStringconverter(dataGridView2.FilterString);
m_filteredList = m_filteredList.Where(listfilter).ToList();
dataGridView2.DataSource = m_filteredList;
}
}
catch (Exception ex)
{
Log.Error(ex, MethodBase.GetCurrentMethod().Name);
}
}
And this is the function to convert the ADGV filter string to the Dynamic Linq filter string:
private string FilterStringconverter(string filter)
{
string newColFilter = "";
// get rid of all the parenthesis
filter = filter.Replace("(", "").Replace(")", "");
// now split the string on the 'and' (each grid column)
var colFilterList = filter.Split(new string[] { "AND" }, StringSplitOptions.None);
string andOperator = "";
foreach (var colFilter in colFilterList)
{
newColFilter += andOperator;
// split string on the 'in'
var temp1 = colFilter.Trim().Split(new string[] { "IN" }, StringSplitOptions.None);
// get string between square brackets
var colName = temp1[0].Split('[', ']')[1].Trim();
// prepare beginning of linq statement
newColFilter += string.Format("({0} != null && (", colName);
string orOperator = "";
var filterValsList = temp1[1].Split(',');
foreach (var filterVal in filterValsList)
{
// remove any single quotes before testing if filter is a num or not
var cleanFilterVal = filterVal.Replace("'", "").Trim();
double tempNum = 0;
if (Double.TryParse(cleanFilterVal, out tempNum))
newColFilter += string.Format("{0} {1} = {2}", orOperator, colName, cleanFilterVal.Trim());
else
newColFilter += string.Format("{0} {1}.Contains('{2}')", orOperator, colName, cleanFilterVal.Trim());
orOperator = " OR ";
}
newColFilter += "))";
andOperator = " AND ";
}
// replace all single quotes with double quotes
return newColFilter.Replace("'", "\"");
}
...and finally the sort function looks like this:
private void dataGridView2_SortStringChanged(object sender, Zuby.ADGV.AdvancedDataGridView.SortEventArgs e)
{
try
{
if (string.IsNullOrEmpty(dataGridView2.SortString) == true)
return;
var sortStr = dataGridView2.SortString.Replace("[", "").Replace("]", "");
if (string.IsNullOrEmpty(dataGridView2.FilterString) == true)
{
// the grid is not filtered!
m_dataGridBindingList = m_dataGridBindingList.OrderBy(sortStr).ToList();
dataGridView2.DataSource = m_dataGridBindingList;
}
else
{
// the grid is filtered!
m_filteredList = m_filteredList.OrderBy(sortStr).ToList();
dataGridView2.DataSource = m_filteredList;
}
}
catch (Exception ex)
{
Log.Error(ex, MethodBase.GetCurrentMethod().Name);
}
}
Finally, you will need the Dynamic Linq library from here
You can use Nuget to bring it into your project:
Install-Package System.Linq.Dynamic
DataTable OrignalADGVdt = null;
private void advancedDataGridView1_FilterStringChanged(object sender, Zuby.ADGV.AdvancedDataGridView.FilterEventArgs e)
{
Zuby.ADGV.AdvancedDataGridView fdgv = advancedDataGridView1;
DataTable dt = null;
if (OrignalADGVdt == null)
{
OrignalADGVdt = (DataTable)fdgv.DataSource;
}
if (fdgv.FilterString.Length > 0)
{
dt = (DataTable)fdgv.DataSource;
}
else//Clear Filter
{
dt = OrignalADGVdt;
}
fdgv.DataSource = dt.Select(fdgv.FilterString).CopyToDataTable();
}
Here follow my code sample for filter advanced datagrid
string myFilter = "(Convert([myCol],System.String) IN ('myfilter'))"
dg.LoadFilterAndSort(myFilter, "");
and to clear filter
dg.CleanFilter();

Release Invoice and Inventory Issue in code

I have a routine to release an invoice and post to inventory that worked in v6.1. I think it was working in 2017R2 also, but I don't know for sure. It does not seem to work at all in 2018R1. The invoice releases, but the inventory issue is not released. The automations are all set to automatically release the issue and they work when processed manually. Only my code does not release the issue. I am at a loss as to why. Any ideas?
============================================================
I have updated the code to the latest version based on your suggestions, but the inventory issue is still not released.
foreach (EDASNShipment asnShipment in PXSelect<EDASNShipment,
Where<EDASNShipment.aSNNbr, Equal<Required<EDASN.aSNNbr>>>>.Select(this, asn.ASNNbr))
{
soShipmentGraph.Clear();
SOShipment soShipment = soShipmentGraph.Document.Search<SOShipment.shipmentNbr>(asnShipment.ShipmentNbr);
var soShipmentExt = PXCache<SOShipment>.GetExtension<SOShipmentExt>(soShipment);
SOOrderShipment soOrderShipment = PXSelect<SOOrderShipment,
Where<SOOrderShipment.shipmentNbr, Equal<Required<SOOrderShipment.shipmentNbr>>>>.Select(this, asnShipment.ShipmentNbr);
ARInvoice arInvoice = PXSelect<ARInvoice, Where<ARInvoice.refNbr, Equal<Required<ARInvoice.refNbr>>,
And<ARInvoice.docType, Equal<Required<ARInvoice.docType>>>>>.Select(this, soOrderShipment.InvoiceNbr, "INV");
if (soShipment.Status != "C")
{
if (autoReleaseInvoices)
{
if (arInvoice != null)
{
/*
soInvoiceGraph.Clear();
soInvoiceGraph.Document.Current = arInvoice;
soInvoiceGraph.release.Press();
var a = new PXAdapter(soShipmentGraph.Document)
{
Searches = new object[] { soShipment.ShipmentNbr }
};
//Note: Post Invoice to IN is Action 3
a.Arguments.Add("actionID", 3);
a.MassProcess = false; //Don't pop up invoice screen
a.MaximumRows = 1;
PXLongOperation.StartOperation(this, () =>
{
foreach (SOShipment shipment in soShipmentGraph.action.Press(a))
{
shipment.ShipmentNbr = shipment.ShipmentNbr;
}
});
*/
//Release Invoice
PXLongOperation.StartOperation(this, delegate ()
{
soInvoiceGraph.Clear();
soInvoiceGraph.Document.Current = arInvoice;
soInvoiceGraph.release.Press();
//Update IN on Shipment
soShipmentGraph.Clear();
soShipmentGraph.Document.Current =
soShipmentGraph.Document.Search<SOShipment.shipmentNbr>(asnShipment.ShipmentNbr);
soShipmentGraph.UpdateIN.Press();
});
}
else
{
statusText += String.Format("Acumatica Invoice could not be located: {0} ", soOrderShipment.InvoiceNbr);
errorOccurred = true;
bolAtLeastOneError = true;
}
}
}
soShipmentGraph.Clear();
soShipment = soShipmentGraph.Document.Search<SOShipment.shipmentNbr>(asnShipment.ShipmentNbr);
soShipmentExt = PXCache<SOShipment>.GetExtension<SOShipmentExt>(soShipment);
soShipmentExt.UsrEDIStatus = "S"; //Sent
soShipmentGraph.Document.Update(soShipment);
soShipmentGraph.Persist();
}
You can refer below code and revise yours
using System.Collections;
using PX.Data;
using PX.Objects.AR;
using PX.Objects.SO;
namespace PXDemoPkg
{
public class SOShipmentEntryPXExt : PXGraphExtension<SOShipmentEntry>
{
public PXAction<SOShipment> DummyCustomAction;
[PXButton()]
[PXUIField(DisplayName = "Dummy Custom Action",
MapEnableRights = PXCacheRights.Select,
MapViewRights = PXCacheRights.Select)]
protected virtual IEnumerable dummyCustomAction(PXAdapter adapter)
{
SOShipment shipment = Base.Document.Current;
SOOrderShipment soOrderShipment = PXSelect<SOOrderShipment,
Where<SOOrderShipment.shipmentNbr, Equal<Required<SOOrderShipment.shipmentNbr>>>>.
Select(Base, shipment.ShipmentNbr);
ARInvoice arInvoice = PXSelect<ARInvoice, Where<ARInvoice.refNbr, Equal<Required<ARInvoice.refNbr>>,
And<ARInvoice.docType, Equal<Required<ARInvoice.docType>>>>>.
Select(Base, soOrderShipment.InvoiceNbr, "INV");
PXLongOperation.StartOperation(Base, delegate ()
{
SOInvoiceEntry soInvoiceGraph = PXGraph.CreateInstance<SOInvoiceEntry>();
SOShipmentEntry soShipmentGraph = PXGraph.CreateInstance<SOShipmentEntry>();
//Release Sales Invoice
soInvoiceGraph.Clear();
soInvoiceGraph.Document.Current = soInvoiceGraph.Document.Search<ARInvoice.docType, ARInvoice.refNbr>(arInvoice.DocType, arInvoice.RefNbr);
soInvoiceGraph.release.Press();
//Update IN on Shipment
soShipmentGraph.Clear();
soShipmentGraph.Document.Current = soShipmentGraph.Document.Search<SOShipment.shipmentNbr>(shipment.ShipmentNbr);
soShipmentGraph.UpdateIN.Press();
});
return adapter.Get();
}
}
}
After much browsing through the code repository, I found some code for releasing issues. I adapted it to my situation and came up with the solution below which works. I am posting it in case someone else is in a similar situation.
if (arInvoice != null)
{
//Release Invoice
PXLongOperation.StartOperation(this, delegate ()
{
soInvoiceGraph.Clear();
soInvoiceGraph.Document.Current = arInvoice;
soInvoiceGraph.release.Press();
//Lookup issue, add to list, and call release
INRegister issue = PXSelect<INRegister,
Where<INRegister.sOShipmentNbr, Equal<Required<INRegister.sOShipmentNbr>>,
And<INRegister.docType, Equal<Required<INRegister.docType>>>>>
.Select(this, asnShipment.ShipmentNbr, INDocType.Issue);
//Check setup flag and issue status
if (sosetup.Current.AutoReleaseIN == true &&
issue.Hold == false &&
issue.Released == false)
{
List<INRegister> issues = new List<INRegister>();
issues.Add(issue);
INDocumentRelease.ReleaseDoc(issues, false);
}
});
}

How can I change the title of the welcomepage programatically?

The code below is not working. (no exceptions thrown). Totally clueless why is not changed When I check in the GUI, there is a new version, with no changes!
public static void SetEntityWebName(ProcessEntity entity, SPWeb entityWeb)
{
try
{
entityWeb.AllowUnsafeUpdates = true;
var welcomePageListItem = entityWeb.GetFile(entityWeb.RootFolder.WelcomePage).Item;
var welcomePage = entityWeb.GetFile(entityWeb.RootFolder.WelcomePage);
welcomePage.CheckOut();
if (entity.Type == Entity.Job)
{
entityWeb.Title = ((SyncJobs_Result)entity.Entity).JobName;
welcomePageListItem["Title"] = ((SyncJobs_Result)entity.Entity).JobName;
welcomePage.Update();
}
if (entity.Type == Entity.Client)
{
entityWeb.Title = ((SyncClients_Result)entity.Entity).ClientName;
welcomePageListItem["Title"] = ((SyncClients_Result)entity.Entity).ClientName;
welcomePage.Update();
}
if (entity.Type == Entity.Opportunity)
{
entityWeb.Title = ((SyncOpportunities_Result)entity.Entity).OpportunityName;
welcomePageListItem["Title"] = ((SyncOpportunities_Result)entity.Entity).OpportunityName;
welcomePage.Update();
}
welcomePage.CheckIn(string.Empty);
welcomePage.Publish(string.Empty);
entityWeb.Update();
}
catch (Exception ex)
{
}
}
I think you also have to update the welcomePageListItem list item .
I am not sure but , give it a try

Categories

Resources