Using Response.BinaryWrite on button click - pdf-generation

I have a button click event and in it am calling this method to generate pdf. This works fine the first time i click on the button but it does not work if i click on the button again to do the opeartion again. Thanks.
private void CreatePDF(Customer c)
{
Response.ClearHeaders();
Response.ClearContent();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment; filename=test.pdf;");
Response.BinaryWrite(GetPrintableCustomer(c));
Response.End();
}

Related

Handling swipes with modal pages

I have a modal page that contains an absolute layout space in which I insert my widgets, in particular a scrollable list widget, which is a custom class derived from AbsoluteLayout:
public ListWidget(List<ListItem> items)
{
list_items = items;
BackgroundColor = Color.Transparent;
tap = new TapGestureRecognizer();
tap.Tapped += Tap_Handler;
list = new ListView()
{
BackgroundColor = Color.Transparent,
HasUnevenRows = true,
VerticalOptions = LayoutOptions.Center
};
list.ItemTapped += Tap_Handler;
list.ItemTemplate = new DataTemplate(typeof(CustomCell));
list.ItemsSource = list_items;
SetLayoutBounds(list, new Rectangle(0.0, 0.0, 1.0, 1.0));
SetLayoutFlags(list, AbsoluteLayoutFlags.All);
Children.Add(list);
}
Nothing fancy, as you see. Now, the page (a ContentPage) in question is loaded by a PushModalAsync() call, but here comes the problem:
If I swipe down on the list, the modal page gets hidden and I cannot get it back, since when I try I get this warning:
Warning: Attempt to present <Xamarin_Forms_Platform_iOS_ModalWrapper: 0x7f970601c580> on <Xamarin_Forms_Platform_iOS_PageRenderer: 0x7f9703f54b50> whose view is not in the window hierarchy!
Apparently, no PopModalAsync() is called in this case.
I have tried overriding this by using a gesture recognizer:
// in the constructor...
space.GestureRecognizers.Add(swipeDown);
listwidget.GestureRecognizers.Add(swipeDown);
}
// where my hopes crushed
void Swiper_Handler(object sender, SwipedEventArgs e)
{
System.Diagnostics.Debug.Print("SWIPED sender {0} args {1}", sender, e);
if (sender == listwidget)
{
System.Diagnostics.Debug.Print("LIST WIDGET! ABORT!");
return;
}
switch (e.Direction)
{
case SwipeDirection.Left:
System.Diagnostics.Debug.Print("Swiped to LEFT");
break;
case SwipeDirection.Right:
System.Diagnostics.Debug.Print("Swiped to RIGHT");
break;
case SwipeDirection.Up:
System.Diagnostics.Debug.Print("Swiped to UP");
break;
case SwipeDirection.Down:
System.Diagnostics.Debug.Print("Swiped to DOWN");
Navigation.PopModalAsync();
break;
}
}
But it won't work:
enabling swipe down on space will pop the page, but I cannot scroll the list
enabling swipe down on listwidget will hide the page, I cannot scroll the list, and I get the above error
removing gestures will hide the page, I cannot scroll the list, and I get the above error
enabling swipe on both space and listwidget will pop the page, but I cannot scroll the list
How can I make a scrollable list with a modal page coexist?
Any hints are greatly appreciated.

Listview from arrayadapter filled text file always one update behind

I have a listview that I want to update with information from a textfile (rollcall.txt). Each time rollcall.txt is updated I am calling rollcall() (code below). The data is updated correctly in the text file before rollcall() is called, I have checked. The problem I have is that the listview doesnt show the updated entry until the next time I call rollcall() (I.E it always appears to be one update step behind).
Where am I going wrong?
public void rollcall(){
String[] splitdata = null;
try{
File myFile = new File(Environment.getExternalStorageDirectory() + "/rollcall.txt");
FileInputStream fIn = new FileInputStream(myFile);
BufferedReader myReader = new BufferedReader(
new InputStreamReader(fIn));
String aDataRow = "";
String aBuffer = "";
while ((aDataRow = myReader.readLine()) != null) {
aBuffer += aDataRow + "\n";
}
splitdata = aBuffer.split("`"); //recover the file and split it based on `
myReader.close();
}
catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.logbooklayout, splitdata);
lv1.setAdapter(adapter);
adapter.notifyDataSetChanged(); //called to ensure updated data is refreshed into listview without reload
EDIT: rollcall is called from this method:
public void onClick(View v) {
if (v==badd){
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("ROLLCALL"); //Set Alert dialog title here
alert.setMessage("Enter data: "); //Message here
// Set an EditText view to get user input
final EditText input = new EditText(this);
alert.setView(input);
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//You will get as string input data in this variable.
// here we convert the input to a string and show in a toast.
add = input.getEditableText().toString();
try {
File myFile = new File(Environment.getExternalStorageDirectory() + "/rollcall.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile, true);
OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
myOutWriter.append(add);
myOutWriter.append("`"); // ` used to split the file down later in lv section
myOutWriter.close();
fOut.close();
}
catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
} // End of onClick(DialogInterface dialog, int whichButton)
}); //End of alert.setPositiveButton
alert.setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
dialog.cancel();
}
}); //End of alert.setNegativeButton
AlertDialog alertDialog = alert.create();
alertDialog.show();
rollcall();
}//end badd
}
Thanks for the help, I am new to using arrayadapters.
Andy
Short answer to your question is everything in UI thread is asynchronous and unless you somehow manage to freeze/lock the whole application you can't make the rest of your UI wait for your alert to grab the input. So long before you press "OK" button in your alert, your rollcall() method is being called from your onClick() function and whatever is inside your .txt file is being read/displayed on your UI, right behind your alert dialog hanging on for you to press one of the buttons, asynchronously.
Maybe the fastest solution to what you want to achieve is to call your rollcall() function somewhere else, after you confirm that your adapter's feeding data has actually been changed. If you must call it from within onClick() function, without questioning your reasons to do so, you should call it inside the try{} block, right after you close the output stream.
Like this:
try {
File myFile = new File(Environment
.getExternalStorageDirectory() + "/rollcall.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile, true);
OutputStreamWriter myOutWriter = new OutputStreamWriter(
fOut);
myOutWriter.append(add);
myOutWriter.append("`"); // ` used to split the
// file down later
// in lv section
myOutWriter.close();
fOut.close();
rollcall();
}
The reason this "works" is you already declared the listener for your "OK" button and whenever you press it, whatever inside your EditText input will be written on file. In order to make it work as before I think you need superhuman skills to write some text on alert dialog and click on button before rollcall() function is called in the same scope.
Obviously the better way to do update the list view is to be able to use adapter.notifyDataSetChanged() but I believe you should call it somewhere else than where you write on your file and in that case your adapter must be declared outside the scope of rollcall() function.
Anyways in order to show how it all goes on I created a simple(rather ugly) android application and put some logs on where the mysterious stuff is happening:
public class MainActivity extends Activity {
private ListView lv1;
private Button refreshButton;
ArrayAdapter<String> adapter;
String[] splitdata;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
refreshButton = (Button) findViewById(R.id.refreshButton);
lv1 = (ListView) findViewById(R.id.someTextViewId);
refreshButton.setOnClickListener(myButtonhandler);
splitdata = null;
}
View.OnClickListener myButtonhandler = new View.OnClickListener() {
public void onClick(View v) {
Log.d("main", "la noliy");
someFunction();
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void someFunction() {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle("ROLLCALL"); // Set Alert dialog title here
alert.setMessage("Enter data: "); // Message here
// Set an EditText view to get user input
final EditText input = new EditText(this);
alert.setView(input);
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// You will get as string input data in this
// variable.
// here we convert the input to a string and show in
// a toast.
String add = input.getEditableText().toString();
try {
File myFile = new File(Environment
.getExternalStorageDirectory() + "/rollcall.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile, true);
OutputStreamWriter myOutWriter = new OutputStreamWriter(
fOut);
myOutWriter.append(add);
myOutWriter.append("`"); // ` used to split the
// file down later
// in lv section
myOutWriter.close();
fOut.close();
if (splitdata.length > 0) {
rollcall(new String("call from inside"));
}
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
} // End of onClick(DialogInterface dialog, int
// whichButton)
}); // End of alert.setPositiveButton
alert.setNegativeButton("CANCEL",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
dialog.cancel();
}
}); // End of alert.setNegativeButton
AlertDialog alertDialog = alert.create();
alertDialog.show();
Log.d("someFunction", "before rollcall");
Log.d("someFunction", "location: "
+ Environment.getExternalStorageDirectory().getAbsolutePath());
rollcall(new String("call from outside"));
Log.d("someFunction", "after rollcall");
}// end badd
public void rollcall(String message) {
Log.d("rollcall", message);
try {
File myFile = new File(Environment.getExternalStorageDirectory()
+ "/rollcall.txt");
FileInputStream fIn = new FileInputStream(myFile);
BufferedReader myReader = new BufferedReader(new InputStreamReader(
fIn));
String aDataRow = "";
String aBuffer = "";
while ((aDataRow = myReader.readLine()) != null) {
aBuffer += aDataRow + "\n";
}
splitdata = aBuffer.split("`"); // recover the file and split it
// based on `
myReader.close();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT)
.show();
}
int length = splitdata.length;
for (int i = 0; i < length; i++) {
Log.d("rollcall", splitdata[i]);
}
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, splitdata);
lv1.setAdapter(adapter);
}
}
I put a button and an onClickListener to it. The first time you press the button everything is called, listview is updated and your dialog is hanging on your screen for either of the buttons to be pressed:
And you will see a log like this:
07-26 04:09:20.802: D/someFunction(11273): before rollcall
07-26 04:09:20.802: D/someFunction(11273): location: /mnt/sdcard
07-26 04:09:20.802: D/rollcall(11273): call from outside
07-26 04:09:20.802: D/rollcall(11273): some data
07-26 04:09:20.802: D/rollcall(11273): some other data
07-26 04:09:20.812: D/someFunction(11273): after rollcall
You can see that rollcall() has been called from outside and not inside of your try/catch block since there is also another call from there to rollcall(). But when you press the button your try/catch block will do it's job inside your onClick() function and rollcall() will be called afterwards. Hence your listview wil be updated with new data you just entered in the dialog:
Here is the final part of log right after you press "OK" you can see that rollcall() is being called and it can read the new data:
07-26 04:09:46.347: D/rollcall(11273): call from inside
07-26 04:09:46.357: D/rollcall(11273): some data
07-26 04:09:46.357: D/rollcall(11273): some other data
07-26 04:09:46.357: D/rollcall(11273): new data
Finally, I'm sure there are a lot of ugliness in this whole approach to your problem. Bottom line is you need to know that everything happening in the UI thread is asynchronous and no one is waiting for you to enter data inside your dialog in that onClick() function. You should update your listview somewhere else with a more elegant approach in case your application throws an exception for example around that try/catch block. At least maybe you should add a finally{} block at the end of it and update your listview in there even though the try part fails. Hope this answered your question:)
PS. For those who want to try this at home, remember to provide a TextView id from your layout.xml file to the findViewById() function to get the ListView reference in your code, not an actual ListView id. Yeah, I know...
call adapter.notifyDataSetChanged() everytime you update your adapter, then listview will automatically be updated
I suggest you run rollcall as an asychronous task for 2 reasons. First, it will not stop your UI when rollcall() is running.
Second, you will be able to call onPostExecute(Object o) wher you can call `adapter.notifyDataSetChanged(); '

Outlook Event is not getting fired on click of custom button

I am developing a Microsoft Outlook Add-in, where I have added one button in Add-In tab name OPENISMS. I could see the button, however on click the event is not getting fired. I have no clue why it is behaving in this manner. Please find below are code for adding button and attaching event to it. Any help will be highly appreciated.
private void AddButtonToNewDropdown()
{
Office.CommandBar commandBar = this.Application.ActiveExplorer().CommandBars["Standard"];
Office.CommandBarControl ctl = commandBar.Controls["&New"];
if (ctl is Office.CommandBarPopup)
{
Office.CommandBarButton commandBarButton;
Office.CommandBarPopup newpopup = (Office.CommandBarPopup)ctl;
commandBarButton = (Office.CommandBarButton)newpopup.Controls.Add(1, missing, missing, missing, true);
commandBarButton.Caption = "OpenISMS";
commandBarButton.Tag = "OpenISMS";
commandBarButton.FaceId = 6000;
//commandBarButton.Enabled = false;
commandBarButton.OnAction = "OpenISMSThruMail.ThisAddIn.ContextMenuItemClicked";
commandBarButton.Click += new Office._CommandBarButtonEvents_ClickEventHandler(ContextMenuItemClicked);
}
}
private void ContextMenuItemClicked(CommandBarButton Ctrl, ref bool CancelDefault)
{
if (currentExplorer.Selection.Count > 0)
{
object selObject = currentExplorer.Selection[1];
if (selObject is MailItem)
{
// do your stuff with the selected message here
MailItem mail = selObject as MailItem;
MessageBox.Show("Message Subject: " + mail.Subject);
}
}
}
I am calling AddButtonToNewDropdown() method from ThisAddIn_Startup event.
You need to make the CommandBarButton a class-member variable in scope - otherwise it will be garbage collected and the event will not fire as you've observed.
public class ThisAddIn
{
Office.CommandBarButton commandBarButton;
private void AddButtonToNewDropdown()
{
// ...
}
}
See related SO post regarding similar issue.

Live title goes into infinite loop

I use live title to launch a specific page:
Live tile in Home screen --launch--> P1 after a task and goto --> P2 --> MainPage
When you click back button in MainPage the app won't exit instead it goes to P2 in a loop fashion.
Here is the code:
try
{
ShellTile TileToFind = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("PageTakePic.xaml"));
if (TileToFind == null)
{
StandardTileData NewTileData = new StandardTileData
{
//BackgroundImage = new Uri("Red.jpg", UriKind.Relative),
//--front tile
Title = "Take Pic",
//Count = 12,
BackTitle = "Quick Access",
//--40 char
BackContent = "Take Pic",
//BackBackgroundImage = new Uri("Blue.jpg", UriKind.Relative)
};
// Create the Tile and pin it to Start. This will cause a navigation to Start and a deactivation of our application.
ShellTile.Create(new Uri("/PageTakePic.xaml", UriKind.Relative), NewTileData);
}
else
{
MessageBox.Show("A live title created for this service already.");
}
}
catch (Exception ex)
{
MessageBox.Show("Try again. Error encountered: " + ex.Message);
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
Update:
Live tile in Home screen --launch--> P1 (PageTakePic.xaml) --> P2 --> MainPage
using below method not working In MainPage. It still goes into a loop:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
NavigationService.RemoveBackEntry();
}
It's a common issue to consider with Deep Links from Live Tiles in Mango. What you need to do is remove the BackStack entries when you hit your Main Page so that hitting the back button will exit the app.
Here is a snippet that may help:
void ClearBackStack()
{
while (NavigationService.CanGoBack)
{
NavigationService.RemoveBackEntry();
}
}
If you handle errors by navigating to home page like in your example:
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
Then it is possible that at some point when you navigate back - you get an error and navigate to MainPage instead, so your live tile gets you to PageTakePic, then when you press back - navigation fails and you navigate forward instead to MainPage. Then the back button gets you back to PageTakePic and so on...

Show applicationbar menu programmatically (wp7)

I have a wp7 with some buttons in the application bar.
When each button is pressed I change the menuItems of the application bar's menu.
After this, I want to automatically open the menu when an application bar button is pressed.
But it seems that the SDK doesn't allow me to do that.
Do you know any work around?
I was thinking, if the above is not possible, to simulate a user finger click at the bottom right corner of the screen to open the menu. Any ideas on that?
Thanx in advance
It's possible to change the Application Bar Menu Items in response to an Icon Button click as demonstrated in the code below.
There isn't a way to forcibly open (or close) the application bar through code through.
It also isn't possible to simulate a finger click on the application bar as this isn't part of the actual page. Note that even if possible any click would need to be in the top right or bottom left if the device was in a landscape orientation.
Here's some code which demonstrates changing the menu items:
public partial class MainPage : PhoneApplicationPage
{
private ApplicationBar appbar;
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
appbar = new ApplicationBar();
var ib1 = new ApplicationBarIconButton(new Uri("/images/one.png", UriKind.Relative)) { Text = "Option one" };
ib1.Click += new EventHandler(ShowMenuOption1);
var ib2 = new ApplicationBarIconButton(new Uri("/images/two.png", UriKind.Relative)) { Text = "Option two" };
ib2.Click += new EventHandler(ShowMenuOption2);
appbar.Buttons.Add(ib1);
appbar.Buttons.Add(ib2);
// Show menu option 1 as default
DisplayMenuOption1();
this.ApplicationBar = appbar;
}
private void DisplayMenuOption1()
{
appbar.MenuItems.Clear();
var itemA = new ApplicationBarMenuItem("AAAA");
var itemB = new ApplicationBarMenuItem("BBB");
appbar.MenuItems.Add(itemA);
appbar.MenuItems.Add(itemB);
}
private void DisplayMenuOption2()
{
appbar.MenuItems.Clear();
var itemC = new ApplicationBarMenuItem("CCCC");
var itemD = new ApplicationBarMenuItem("DDDD");
appbar.MenuItems.Add(itemC);
appbar.MenuItems.Add(itemD);
}
private void ShowMenuOption2(object sender, EventArgs e)
{
DisplayMenuOption2();
}
private void ShowMenuOption1(object sender, EventArgs e)
{
DisplayMenuOption1();
}
}
As far as I'm aware this capability has not been exposed as yet. It wasn't possible during beta and I've not noticed anything that's changed since that would allow it. You could always comment on the their suggestions forum or raise it on connect (vs/wpdt).

Resources