I have problems updating my UITableView from an AsyncCallback but updating a label works fine?
My code looks like this:
private void ProcessHttpResponse(IAsyncResult iar) {
// Do some work ...
InvokeOnMainThread(delegate {
myTable.Source = new MyTableViewSource(this.Controller,result.Messages);
txtInfo.Text += "Received request from: ";
});
}
Do I need to do something else with my table besides setting the source?
Isnt there a ReloadData() or something on the myTable.Source?
I would also add a bit more validation of the response before adding it to the datasource, and bung it all in a nice try / catch :)
Related
I have a custom module that uses Kentico API (DocumentHelper) to update certain fields of my document and then publish but I do not want it to trigger the event handlers that are linked to my document page type. I tried adding comments to .Publish("admin_edit") hoping that I can catch it from the WorkflowEventargs parameter but the VersionComment property always return null. Is there a way to accomplish this in Kentico?
update field:
var document = DocumentHelper.GetDocument(documentID, tree);
var workflowManager = WorkflowManager.GetInstance(tree);
var workflow = workflowManager.GetNodeWorkflow(document);
if (workflow != null)
{
document.CheckOut();
document.SetValue("SomeFIeld", "some value");
document.Update(true);
document.CheckIn();
document.Publish("admin_edit");
}
event handler:
public override void Init()
{
WorkflowEvents.Publish.After += Publish_After;
}
private void Publish_After(object sender, WorkflowEventArgs e)
{
if (!string.IsNullOrEmpty(e.VersionComment) &&
e.VersionComment.Contains("admin_edit"))
return;
}
You always get null for Version information, because that is related to the 'Page versioning' events, specially for 'SaveVersion'. You can find more about that on this link. If you expand 'Properties' you will see which properties are populated for the specific event. In your case, you can try something like this, to add your message for last version and then check for that comment on 'Publish_After' event, see code bellow:
var document = DocumentHelper.GetDocument(documentID, tree);
var workflowManager = WorkflowManager.GetInstance(tree);
var workflow = workflowManager.GetNodeWorkflow(document);
if (workflow != null)
{
document.CheckOut();
document.SetValue("SomeFIeld", "some value");
document.Update(true);
document.CheckIn(versionComment: "admin_edit");
document.Publish();
}
and then, in event handler, take last version and check for comment like this:
if (e.PublishedDocument?.VersionHistory?.Count > 0)
{
var lastVersion = e.PublishedDocument.VersionHistory[0] as VersionHistoryInfo;
if (lastVersion.VersionComment.Equals("admin_edit"))
{
return;
}
}
NOTE: In case that you have a lot of concurrent content editors, there is a chance that your last version is not version from API (someone changed content and saved it right after your API call made change). There is a low chance for that, but still is possible. If this is something that you will use often, you must take it in consideration. This code is tested for Kentico 11.
Here's my problem : I'm doing a background work, where I parse some JSON and write some Objects into my Realm, and in the main thread I try to update the UI (reloading the TableView, it's linked to an array of Object). But when I reload the UI, my tableView doesn't update, like my Realm wasn't updated. I have the reload my View to see the updates. Here's my code :
if (Realm().objects(Objects).filter("...").count > 0)
{
var results = Realm().objects(Objects) // I get the existing objects but it's empty
tableView.reloadData()
}
request(.GET, url).responseJSON() {
(request, response, data, error) in
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
// Parsing my JSON
Realm().write {
Realm().add(object)
}
dispatch_sync(dispatch_get_main_queue()) {
// Updating the UI
if (Realm().objects(Objects).filter("...").count > 0)
{
results = Realm().objects(Objects) // I get the existing objects but it's empty
tableView.reloadData()
}
}
}
}
I have to do something bad with my threads, but I couldn't find what. Can someone know what's wrong?
Thank you for your answer!
such workflow makes more sense to me for your case:
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
// Parsing my JSON
Realm().write {
Realm().add(object)
dispatch_sync(dispatch_get_main_queue()) {
// Updating the UI
if (Realm().objects(Objects).filter("...").count > 0)
{
results = Realm().objects(Objects) // I get the existing objects but it's empty
tableView.reloadData()
}
}
}
}
NOTE: you have a problem with timing in your original workflow: the UI might be updated before the write's block executed, that is why your UI looks abandoned; this idea above would be a more synchronised way between tasks, according their performance's schedule.
You are getting some new objects and storing them into "results".
How is tableView.reloadData () supposed to access that variable? You must change something that your tableView delegate will access.
PS. Every dispatch_sync () is a potential deadlock. You are using one that is absolutely pointless. Avoid dispatch_sync unless you have a very, very good reason to use it.
I am getting the following error when i try to update the item's name in the sharepoint
document library. The item is of type document set and its default values is loaded using javascript. In the Item added event we are updating with the new changed item's name value. But in the item.update() code statement i am getting following error.
The File CZY14389 has been modified by domain\username on current date.
Please provide your commens on resolving this.
You cannot change the name of a sharepoint document like that. You need to "move it".
Item.Update();
Item.File.MoveTo(Item.ParentList.RootFolder.Url + "/" + newFileName, false);
Item.File.Item["FileRef"] = newFileName;
Item.File.Update();
before you update item name and call item.update(), can you try to refresh your item like this:
item = item.ParentList.GetItemById(item.ID);
item.name = "xyz";
item.update();
this can sometimes happen in event handler. the problem is the updation process in the event handler is not as the same of the workflow. In event handler for updating you have to use the followitn steps. Dont use Item.Update() as in workflow.
Follow the steps:
• call and disable event firing before your code with : base.EventFiringEnabled = false;
•update your item by calling item.systemUpdate(false);
•enable event firing with : base.EventFiringEnabled = true;
Disable event firing and call your update code, dont forget to enable event firing.
HandleEventFiring handleEventFiring = new HandleEventFiring();
handleEventFiring.DisableHandleEventFiring();
try
{
item.Update();
//if item.Update doesnt work then use(For me item.update worked only on my local not on prod then i used the below)
//item.SystemUpdate(false)
}
finally
{
handleEventFiring.EnableHandleEventFiring();
}
public class HandleEventFiring : SPItemEventReceiver
{
public void DisableHandleEventFiring()
{
//obsolete
//this.DisableEventFiring();
this.EventFiringEnabled = false;
}
public void EnableHandleEventFiring()
{
//obsotete
//this.EnableEventFiring();
this.EventFiringEnabled = true;
}
}
I'm currenty working on a shipping module extension that is used for an order-import script to set to every order the same shipping cost and shipping code.
Everythings works fine but the problem that is, that the shipping method is visible in frontend. I will release this extension later in magento connect, so its not pissible to edit frontend templates.
Does anyone know how to disable the carrier in frontend without disableing the module in backend or changeing the status to inactive and without editing templates? (e.g. a custom block that declines displaying)
Thanks to everyone! Mru
EDIT:
I've tried your tip like this, but it doesn't work:
<blocks>
<checkout>
<rewrite>
<onepage_shipping_method_availible>XXX_XXX_Block_Checkout_Onepage_Shipping_Method_Available</onepage_shipping_method_availible>
</rewrite>
</checkout>
</blocks>
and created this class:
class XXX_XXX_Block_Checkout_Onepage_Shipping_Method_Available extends Mage_Checkout_Block_Onepage_Shipping_Method_Available
{
public function getShippingRates()
{
if (empty($this->_rates)) {
$this->getAddress()->collectShippingRates()->save();
$groups = $this->getAddress()->getGroupedAllShippingRates();
return $this->_rates = $groups;
}
return $this->_rates;
}
}
(I don't know why it is not displayed correctly...)
Thanks for your held, MRu
EDIT2:
Sorry for being so stupid.. The above posted code would work if i were not unable to write 'availalbe'...
Thanks!
You can hide shipping method from front end with observer, write this code in config.xml
<frontend>
<events>
<sales_quote_collect_totals_before>
<observers>
<frontend_shipping_rates_sales_quote_collect_totals_before>
<class>yourmodule/observer</class>
<method>hideShippingMethods</method>
</frontend_shipping_rates_sales_quote_collect_totals_before>
</observers>
</sales_quote_collect_totals_before>
</events>
Second in Observer.php use this code
public function hideShippingMethods( Varien_Event_Observer $observer )
{
if (Mage::getDesign()->getArea() === Mage_Core_Model_App_Area::AREA_FRONTEND)
{
$quote = $observer->getEvent()->getQuote();
$store = Mage::app()->getStore($quote->getStoreId());
$carriers = Mage::getStoreConfig('carriers', $store);
$hiddenMethodCode = 'freeshipping';
foreach ($carriers as $carrierCode => $carrierConfig)
{
if( $carrierCode == $hiddenMethodCode )
{
$store->setConfig("carriers/{$carrierCode}/active", '0');
}
}
}
}
You need to overload the Mage_Checkout_Block_Onepage_Shipping_Method_Available::getShippingRates() method
Well, I'm developing a app in my cellphone that is going to connect to my PC, the problem is that everytime that I return a URLRequest to the cellphone, it shows the previous Form on the screen and not de actual one, for example this is what goes in my actionListener:
public void actionPerformed(ActionEvent ae) {
if (ae.getCommand() == guiaUtil.cSelecionar()) {
LoginRemote loginRemote = new LoginRemote();
try {
//This is the request, returns true or false, does not affect the form
loginRemote.login(tLogin.getText(), tPassword.getText());
} catch (Exception e) {
GuiaUtil.error(e);
return;
}
guiaUtil.mainApp().startMenu();
}
}
Then in the "guiaUtil.mainApp().startMenu()" I have this
public void startMenu() {
if (itemsMenu == null) {
itemsMenu = new List();
itemsMenu.setWidth(320);
itemsMenu.addItem("Sincronize Spots");
itemsMenu.addItem("Find Spots");
itemsMenu.addItem("Work");
itemsMenu.setFocus(true);
this.addComponent(itemsMenu);
this.addCommandListener(this);
this.addCommand(guiaUtil.cSelect());
Form form = new Form();
form.addComponent(itemsMenu);
}
form.show();
}
Anyway, after the request returns, it shows my Login form again, instead of showing the Menu List
Maybe what is going is that you are getting an exception, treating it with GuiaUtil.error and returning from actionPerformed without calling startMenu.
I would move guiaUtil.mainApp().startMenu() inside the try/catch block.
Not sure what happens in loginRemote.login(tLogin.getText(), tPassword.getText());
If you access the network, I would put that part in a different thread.
Inform the main thread by some kind of callback when the "remote login" is done,
you can show the menuForm from the edt then.
You have to put the following code outside the if condition.
Form form = new Form();
form.addComponent(itemsMenu);
You are having two form object. one inside if and another one outside of if. Object created inside the loop will loses the scope inside if. You are showing form object outside if. That's why, menu list screen was not displayed.