I create ListView using ListAdapter on Android Xamarin. I am using it on Activity which extend ListActivity
This is my code
ListAdapter = new ArrayAdapter<string> (
this,
Android.Resource.Layout.SimpleListItem1,
new string[] { "tes1", "tes2", "tes3" }
);
When I put that in Oncreate() it shown. But I do need that ListAdapter to bind some data when some event (says download completed event) so I put it in a method which I call after download data completed but why ListAdapter can't be shown? My ListView become empty. I am using the same code as above.
this is my OnCreate method
base.OnCreate(bundle);
_DataTopStories = new TopStoriesViewModel();
_DataService = new DataService();
SetContentView(Resource.Layout.ListTopStoriesLayout);
_DataService.GetTopStories();
_DataService.DownloadCompleted += _DataService_DownloadCompleted;
this is Download Event Completed
void _DataService_DownloadCompleted(object sender, EventArgs e)
{
var raw = ((DownloadEventArgs)e).ResultDownload;
if(raw!=null)
{
_DataTopStories = JsonConvert.DeserializeObject<TopStoriesViewModel>(raw);
CreateList();
Log.Info("ds", "download completed");
}
}
this is CreateList() method
private void CreateList()
{
Log.Info("ds", "list");
ListAdapter = new ArrayAdapter<string>(Application.Context, Android.Resource.Layout.SimpleListItem1, new string[] { "tes4", "tes52", "tes6" });
Log.Info("ds", "set adapter");
}
And in Android logcat "set adapter" will not shown. It looks stopped on ListAdapter.
Ok. Found my solution. To update ListAdapter I need to run it on UI Thread so this is my new Download Completed Event
void _DataService_DownloadCompleted(object sender, EventArgs e)
{
var raw = ((DownloadEventArgs)e).ResultDownload;
if(raw!=null)
{
_DataTopStories = JsonConvert.DeserializeObject<TopStoriesViewModel>(raw);
RunOnUiThread(() => CreateList());
//CreateList();
Log.Info("ds", "download completed");
}
}
Related
Hello I have the following code
public class MainActivity : Activity
{
Button b;
Button c;
TextView t;
List<string> tasks = new List<string>();
ListView lView;
ArrayAdapter<string> adapter;
int count = 0;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
b = FindViewById<Button>(Resource.Id.btn);
c = FindViewById<Button>(Resource.Id.clearBtn);
t = FindViewById<TextView>(Resource.Id.tView);
lView = FindViewById<ListView>(Resource.Id.listView);
adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1,tasks);
lView.Adapter = adapter;
b.Click += ChangeTextAndAdd;
}
}
private void ChangeTextAndAdd(object sender, EventArgs e)
{
t.Text = "text is changed";
string listItem = string.Format("task{0}", count++);
tasks.Add(listItem);
adapter.NotifyDataSetChanged();
}
My question is why doesn't my listview update when I click on my button. I don't understand it because I have used adapter.NotifyDataSetChanged(); but it doesn't work. Is there something I've been missing?
This code only add the item to the list, but doesn't update the array adapter:
tasks.Add(listItem);
Either add the item directly to the adapter:
adapter.Add(listItem);
or after you add the item to the list, clear the adapter and re-add the list to it:
adapter.Clear();
adapter.Add(tasks);
I'm new to the Xamarin world, so I'm in a real need of your help. In my very first application I want to associate a progress bar with a button. So that when I click the button the progress bar starts and when the progress ends the progress bar disappears.
Here is my C# code:
translateButton.Click += (object sender, EventArgs e) =>
{
ProgressBar pb = FindViewById<ProgressBar>(Resource.Id.progressBar1);
Thread.Sleep(1000);
pb.Enabled = true;
translateNumber = Core.PhonewordTranslator.ToNumber(phoneNumberText.Text);
if (string.IsNullOrWhiteSpace(translateNumber))
{
callButton.Text = "Call";
callButton.Enabled = false;
pb.Enabled = true;
}
else
{
callButton.Text = "Call" + translateNumber;
callButton.Enabled = true;
pb.Enabled = true;
}
};
this code from this tutorial on Xamarin website.
Try something like this :
ProgressBar pb;
Button translateButton;
EditText phoneNumberText;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
translateButton = FindViewById<Button>(Resource.Id.translateButton);
phoneNumberText = FindViewById<EditText>(Resource.Id.phoneNumberText);
pb = FindViewById<ProgressBar>(Resource.Id.pb);
pb.Visibility = ViewStates.Invisible;
translateButton.Click += translateButtonClicked;
}
async void translateButtonClicked (object sender, EventArgs e)
{
pb.Visibility = ViewStates.Visible;
await myMethod();
pb.Visibility = ViewStates.Gone;
}
async Task myMethod()
{
await Task.Run(() => {
//
// Do the work stuff here
//
});
}
I have about 8 records that I want to print in one batch, each on a separate page. However, the UWP sample for this uses over 600 lines of code to accomplish it. It seems to me that it has to be much, much easier than that. I thought all we'd have to do is add each page to the PrintDocument and send the print job. Apparently not. I'm using this:
async void Print()
{
var printDocument = new PrintDocument();
var printDocumentSource = printDocument.DocumentSource;
var printMan = PrintManager.GetForCurrentView();
printMan.PrintTaskRequested += PrintTaskRequested;
var pages = new List<Page>();
foreach (var item in items)
{
(//Set up variables)
var printPage = new PageToPrint() { //Set properties };
printPage.Set_Up(); //Set up fields
pages.Add(printPage);
}
printDocument.SetPreviewPage(1, page);
printDocument.SetPreviewPageCount(pages.Count, PreviewPageCountType.Final);
foreach (var page in pages)
{
printDocument.AddPage(page);
}
printDocument.AddPagesComplete();
await PrintManager.ShowPrintUIAsync();
}
void PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs e)
{
PrintTask printTask = null;
printTask = e.Request.CreatePrintTask("Kimble Print Job", sourceRequested =>
{
printTask.Completed += PrintTask_Completed;
sourceRequested.SetSource(printDocumentSource);
});
}
private async void PrintTask_Completed(PrintTask sender, PrintTaskCompletedEventArgs args)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
PrintManager printMan = PrintManager.GetForCurrentView();
printMan.PrintTaskRequested -= PrintTaskRequested;
});
}
However, it won't generate the print preview. It just sits there spinning and spinning, and if I hit "print" it doesn't succeed (PDF can't open, job never gets to a physical printer.)
I was hoping printing would be at least reasonably easy with the PrintDocument, and I still think it looks like it should be. Am I just missing it here, or does it really take 600+ lines of code to dispatch a simple print job?
However, it won't generate the print preview.
This is because the setPreview method printDocument.SetPreviewPage(1, page); must be put in printDocument.GetPreviewPageevent handle. So you should register the event handle firstly. Same with printDocument.AddPages event handle.You messed up the event handle register and callback function all in one.Here I do a little change of your code and I tested it works well.
protected PrintDocument printDocument;
protected IPrintDocumentSource printDocumentSource;
List<Page> pages = new List<Page>();
Page printPage = new PageToPrint();
public MainPage()
{
this.InitializeComponent();
RegisterForPrinting();
}
private async void BtnPrint_Click(object sender, RoutedEventArgs e)
{
await PrintManager.ShowPrintUIAsync();
}
public void RegisterForPrinting()
{
printDocument = new PrintDocument();
printDocumentSource = printDocument.DocumentSource;
pages.Add(printPage);
printDocument.GetPreviewPage += GetPrintPreviewPage;
printDocument.AddPages += AddPrintPages;
PrintManager printMan = PrintManager.GetForCurrentView();
printMan.PrintTaskRequested += PrintTaskRequested;
}
private void AddPrintPages(object sender, AddPagesEventArgs e)
{
foreach (var page in pages)
{
printDocument.AddPage(page);
}
printDocument.AddPagesComplete();
}
private void GetPrintPreviewPage(object sender, GetPreviewPageEventArgs e)
{
printDocument.SetPreviewPage(1, printPage);
printDocument.SetPreviewPageCount(pages.Count, PreviewPageCountType.Final);
}
void PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs e)
{
PrintTask printTask = null;
printTask = e.Request.CreatePrintTask("Kimble Print Job", sourceRequested =>
{
printTask.Completed += PrintTask_Completed;
sourceRequested.SetSource(printDocumentSource);
});
}
private async void PrintTask_Completed(PrintTask sender, PrintTaskCompletedEventArgs args)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
PrintManager printMan = PrintManager.GetForCurrentView();
printMan.PrintTaskRequested -= PrintTaskRequested;
});
}
Although you may not need all the code of the sample, but I recommend you to follow the official sample structure and build a PrintHelper class.
I have a class SendCountingInfo() and it will send a message to server every 5 minutes. The code inside this class are:
public void StartSendCountingInfo()
{
DoStartSendCountingInfo(300000);
}
private void DoStartSendCountingInfo(int iMiSecs)
{
_pingTimer = new System.Timers.Timer(iMiSecs);
_pingTimer.Elapsed += new System.Timers.ElapsedEventHandler(pingTimer_Elapsed);
_pingTimer.Start();
}
void pingTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
PingRemoteHost();
}
When I try to call it in the Windows Form class, it didn't work.
But, when I remove the timer and call PingRemoteHost() directly, it works. However, the form didn't load properly. It shows blank screen but the method PingRemoteHost() work.
Here is the code inside the windows form:
private void Layout_Load(object sender, EventArgs e)
{
tSystemChecker = new System.Timers.Timer(1000);
tSystemChecker.Elapsed += new System.Timers.ElapsedEventHandler(tSystemChecker_Elapsed);
tSystemChecker.Start();
this.WindowState = FormWindowState.Maximized;
}
void tSystemChecker_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
UIThreadWork(this, delegate
{
try
{
SuspendLayout();
DoCheckHardwareStatus();
DoCheckLanguage();
SendCountingInfo sci = new SendCountingInfo();
sci.StartSendCountingInfo();
}
catch (Exception exp)
{
System.Diagnostics.Debug.WriteLine(exp.Message);
System.Diagnostics.Debug.WriteLine(exp.Source);
System.Diagnostics.Debug.WriteLine(exp.StackTrace);
}
ResumeLayout(true);
});
}
Do you have any idea what's wrong?
Use a thread and see if the problem persist
using System.Threading;
//Put this where you want to start the first timer
Thread thread = new Thread(dowork =>
{
public void StartSendCountingInfo();
}
If you are updating the GUI use for your controls
guicontrol.BeginInvoke((MethodInvoker)delegate()
{
guicontrol.Text = "aa";
//etc
});
I've got this code and I'm using it to show a button which allows the user to choose an image from his library and use it as a background for my app.
So I create a PhotoChooserTask, set it to show the camera and bind it to a method that has to be executed when the task is completed.
The button will start the task by showing the PhotoChooserTask.
The action to do on complete is quite easy, I've just got to set a boolean value and update an image source.
PhotoChooserTask pct_edit = new PhotoChooserTask();
pct_edit.ShowCamera = true;
pct_edit.Completed += pct_edit_Completed;
Button changeImageButton = new Button { Content = "Change Image" };
changeImageButton.Tap += (s, e) =>
{
pct_edit.Show();
};
void pct_edit_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
bi.SetSource(e.ChosenPhoto);
IsRebuildNeeded = true;
}
}
The problem is that it won't show the PhotoChooserTask but it will give me an exception, taking me to
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (Debugger.IsAttached)
{
Debugger.Break();
}
}
in App.xaml.cs.
This looks weird as I've got another PhotoChooserTask in the same class and this one works fine.
What's wrong with it?
VisualStudio won't even tell me what's the exception and so there's no way to figure it out!
EDIT:
I just found out that the exception is thrown when I call
pct_edit.Show();
in the button's tap event.
You should be defining your chooser as a field in your class. It's a requirement that you have page scope for the PhotoChooser. You then subscribe to it in your constructor. This is stated on the MSDN here
class SomeClass
{
readonly PhotoChooserTask pct_edit = new PhotoChooserTask();
SomeClass()
{
pct_edit.ShowCamera = true;
pct_edit .Completed += new EventHandler<PhotoResult>(pct_edit_Completed);
}
}
You can use try to check what is the problem
changeImageButton.Tap += (s, e) =>
{
try
{
PhotoChooserTask pct_edit = new PhotoChooserTask();
pct_edit.ShowCamera = true;
pct_edit.Completed += (s,e) =>
{
if (e.TaskResult == TaskResult.OK)
{
var bi = new BitmapImage() // maybe you didn't initialize bi?
bi.SetSource(e.ChosenPhoto);
IsRebuildNeeded = true;
}
}
pct_edit.Show();
}
catch (Exception ex)
{
Message.Show(ex.Message);
}
};
Put brakepoint on Message, then you can check everything inside ex.