How To Prevent Adding Duplicate row to a DevExpress gridControl - duplicates

I have a gridcontrol bind to Datatable, in my grid i let users to select products for proccessing.
The issue is I don't want users to add same product code twice to the grid.
Is there a way to prevent them adding the same product code twice?
I already tried Unique attirbute in my DataTable bu it didn't quite worked as I needed.
Any help will be appreciated

I normally use GridView.ValidateRow event which should fire when the user has finished editing a row. Event args provides access to the row object via e.Row, an error message via e.ErrorText, and valid status via e.Valid, so it should be a simple matter of grabbing the product code from the updated row and looking for it in the datatable.

I thought of something like this
gridViewDefault.RowLoaded += gridViewDefault_RowLoaded;
Hashtable hashTable = new Hashtable();
void gridViewDefault_RowLoaded(object sender, RowEventArgs e)
{
var obj = ( sender as GridView ).GetRow(e.RowHandle) as OrderDocument;
var uniqueId = obj.Document.DocumentId;
if( hashTable[uniqueId] == null )
hashTable.Add(uniqueId, 1);
else
( sender as GridView ).DeleteRow(e.RowHandle);
}
but then saw that the RowLoaded event only fires in Instant Feedback Mode
Apparently there is no immediate event after a DataSource has finised Loading.
Therefore, instead of event-based, I would go for a function similar to the one I wrote, which Iterates the whole GridView, after you have all the Data.

Related

mvc5 fill List<> before using in HTML

I am using MVC 5 and Visual Studio 2013.
In my HTML I am using
#model namespace.Models.UserViewModel
and my UserViewModel is a model class defined like this.
I have also my Gender class defined like this, where I fill my SexList with Male and Female genders.
What I want to do is to add a radio button for each option in my list.
So in my HTML I add
But in runtime have an error saying
Model.SexList is empty.
My question is how can I fill my list before using it?
The question you posted itself is wrong.
The code where you do
List<Gender> lista = null;
lista.Add(new Gender { ID =1, Type = "Male"});
// ^^ this line gives you run time error as object does not have a instance.
You need to create an instance of the object and then add the items into it
List<Gender> lista = new List<Gender>();
With this change your code is good to exhibit the desired behavior unless you have changed the contents of the SexList else where before the for loop, Which you have not posted in your question.
For what you have posted it seems like you have forgot to instantiate your list.
You should have a lista = new List<Gender>(), as you havenĀ“t instantiate it you should be getting exception trying to add new elements to the list.
Other alternative you could to is to place to SexList initialization in the class constructor:
public UserViewModel()
{
SexList = new List<Gender>();
SexList.Add...
}
Or make it (the SexyList property) static already initializing it.
Regards,
You need to fill SexList in the User object like below
foreach (var user in users)
{
user.SexList=new SexList(){}
}

Prevent Locking of UI Thread

I have a DataGrid on my main page that is full of Employees. Each Employee has an "in" status - this is modified based on whether the Employee is currently in the building or not.
I need to consistently update this DataGrid as people will be entering or leaving the building throughout the day. This means I will be sending MySQL queries somewhere between every 1-5 seconds until the user clicks on a button to navigate to another page.
I have tried the most simple and obvious solution, a While loop however this freezes and locks the UI. How can I create a loop that runs and queries MySQL without locking the UI?
EDIT: Attempted Answer
public void PeriodicCall()
{
var employeeDS = new EmployeeDataService();
int i = 1;
Timer timer = new Timer(
state => {
Employees = employeeDS.HandleEmployeeSelect();
FilteredView = CollectionViewSource.GetDefaultView(Employees);
Application.Current.Dispatcher.BeginInvoke(new Action(() => {
dataGrid.ItemsSource = FilteredView;
testLabel.Content = "Who's Who " + i;
i++;
}));
},
null, //no object as Callback parameter
TimeSpan.FromSeconds(0), //start in x millisec
TimeSpan.FromSeconds(1)); //time between call
}
You can use a Backgroundworker, hook to its .completed and there render (using
BackgroundWoker worker = new BackgroundWorker();
worker.DoWork += functioToDo
worker.Completed += functionWhere you update the UI
worker.runAsynchronous(); //actually starts the thread
In the function that updates the UI don't forget to use the dispatcher to access the UI thread:
dispatcher.invoke((Action) delegate { here your code})
to access the UI thread for elsewhere.
Other cooler approach is to take care of the propertyChanged and bind the changes to the UI. But this is a bit more complex and I don't know the details by head.
You can use a timer to start the whole thing every few seconds.
A third approach would be to have a trigger when you update the data base. We would need more details to know how to attach there. But from there you can also call some updates in the UI and then you don't need to use CPU to check every seconds (you know, work by interruption instead of by polling).
You should use a timer to periodically retrieve data from your DB and update data in your datagrid using the Dispatcher.BeginInvoke function.
Timer timer = new Timer(
state => {
//Callback function
Object yourData = GetDataFromDB();
Application.Current.Dispatcher.BeginInvoke(new Action(()=> {
YourUIProperty = yourData;
}));
},
null, //no object as Callback parameter
TimeSpan.FromSeconds(1), //start in x millisec
TimeSpan.FromSeconds(5) //time between call
);

Cocos2D-X Layer::init() gets stuck when waiting for Leaderboard Service

I'm trying to integrate App42 Leaderboard Service to my Cocos2D-X Game. The core functionality (Sending Scores to Server and retrieving them, just the way shown on the App42 site...) is working fine.
Now i want to visualize my leaderboard data using a CCTableView.
So I got a Leaderboard class (inherited from CCLayer) and am doing something like this :
bool Leaderboard::init() {
...
// Initialize and send App42 Scoreboard API call
App42API::Initialize(API_KEY, SECRET_KEY);
ScoreBoardService *scoreBoardService = App42API::BuildScoreBoardService();
scoreBoardService->GetTopNRankers(gameName,MAX_SCORES, this,app42callfuncND_selector(Leaderboard::onGetTopNRankings));
// responseArrived is boolean, indicates if onGetTopRankings was called
while(!responseArrived);
CCTableView* tableView = CCTableView::create(this, CCSizeMake(400, 100));
tableView->setDirection(kCCScrollViewDirectionVertical);
tableView->setPosition(winSize.width/3 , winSize.height/2);
tableView->setDelegate(this);
tableView->setVerticalFillOrder(kCCTableViewFillTopDown);
this->addChild(tableView,5);
tableView->reloadData();
return true;
}
void HelloWorld::onGetTopNRankings(App42CallBack *sender, void *response){
App42GameResponse *scoreResponse = (App42GameResponse*)response;
if (scoreResponse->isSuccess)
{
// Save User scores to Array
responseScores = scoreResponse->scores;
}
else
{
printf("\nerrordetails:%s",scoreResponse->errorDetails.c_str());
printf("\nerrorMessage:%s",scoreResponse->errorMessage.c_str());
printf("\nappErrorCode:%d",scoreResponse->appErrorCode);
printf("\nhttpErrorCode:%d",scoreResponse->httpErrorCode);
}
// Response Data is saved, or Error occured, go back to init()
responseArrived = true;
}
So as you see, I am waiting for onGetTopNRankings to get called, because the data for my TableView would be empty else. But what happens is, that the I can't get back to init() when onGetTopNRankings returns, it gets stuck.
So anybody got an idea why i can't return to Leaderboard::init() or got any good idea to solve this in any other way, I am open for each suggestion ?
while(!responseArrived);
This blocks the thread (endless loop). You need to fill your table view in the callback method when you have actual data. It will be empty until then. That's something your app's design has to deal with. For instance you could display a "loading" animation in the meantime, with a cancel button on it.
I tested your code and it is working fine in my App42Cocos2dXSample
The only possible reason for the issue you are getting is the owner class name of callback method in your code snippet.
scoreBoardService->GetTopNRankers(gameName,MAX_SCORES,
this,app42callfuncND_selector(Leaderboard::onGetTopNRankings));
In the above statement, onGetTopNRankings belong to the class Leaderboard, but while defining the callback method, it belongs to the class Helloworld:
void HelloWorld::onGetTopNRankings(App42CallBack *sender, void *response){
So, try changing the class name from Helloworld to Leaderboard in the above statement. I hope it will work.

Flex: Cannot get value in array collection

I have an array collection object 'invArrayCol' which holds some data. I also have a datagrid. I have set dataProvider as invArrayCol.I displays the data properly when i use it with data grid. But the same invArrayCol shows null when used anywhere other than datagrid. I wrote this code
protected function titlewindow1_creationCompleteHandler(event:FlexEvent):void
{
Cgt=new CgtSRObject();
var autoobj:CSAutoNumberType=new CSAutoNumberType();
autoobj.addEventListener(ResultEvent.RESULT,getInvNubmer);
autoobj.getInvNo(invoiceType);
trace(robj.salesPerson_Id);
getSalesReturnCgt.token=csInvoicePrint.getCgtData(robj.receive_Id);
getSalesReturnCgt.addEventListener(ResultEvent.RESULT,getInvArrList);
trace(Cgt.sr_no);
datagrid_dataprovider=new ArrayCollection();
datagrid_dataprovider=invArrayCol;
calculateTotal();
}
This 2 lines set data to invArrayCol
getSalesReturnCgt.token=csInvoicePrint.getCgtData(robj.receive_Id);
getSalesReturnCgt.addEventListener(ResultEvent.RESULT,getInvArrList);
But here it gives value of invArrayCol as null.
datagrid_dataprovider=new ArrayCollection();
datagrid_dataprovider=invArrayCol;
Please tell me some way out of this.
The ResultEvent's result may return an ObjectProxy, in case the data is of length 1. Casting via 'as' would lead to a silent failing of the cast. So simply checking the type of the result would let you determine if the result can be used directly or if you have to wrap an ArrayCollection around it.
// This happens asynchronously, should have no effect in the function
getSalesReturnCgt.addEventListener(ResultEvent.RESULT,getInvArrList);
Also, the
// datagrid_dataprovider=new ArrayCollection(); // This line is obsoloete
datagrid_dataprovider=invArrayCol; // invArrayCol will get its value later
So, it looks like your expectation is for some code to have it executed synchronously, but it is always working asynchronously.

Recursive function with event listener in flex 4

I have written a function which is recursively called. I have maintained an array in which values are pushed with a listener of an event. But the problem is function is returned first without array increment and the listener is executed later.
public function getAllChilds(seltem:XML, allChilds:Array): Array
{
if(//the childs of selected item if need to retrive from server)
var viewChildrenJobsService : HTTPService = new HTTPService();
viewChildrenJobsService.url = // here is my url ;
viewChildrenJobsService .addEventListener(ResultEvent.RESULT, function(event:ResultEvent):void {
// now on this result event i got all childs of selected item.
for each(var childJob :XML in seltem.children())
{
allChilds.push(childJob);
if (//the childs of childJob need to retrive from server)
allChilds = getAllHierarchicalChilds(childJob, allChilds);
}
});
return allChilds;
}
Is there any way to overcome this problem so that the function will return after the completion of the event?
ok , you are returning allchilds before the Result Event. You erase the original question ;) , so i dont remember if your problem was this.
Try to split the function : First the request, then get the value of allChild.
and yes ... is better to write (and paste) good formatted code : its easier to understand.