How do I pass a 2D string array to a click event? - c#

I am trying to pass a 2d string array as a parameter to a click event (searchButton_Click) which is generated within a click event so I can perform a search function. However, I get the error No overload for 'searchButton_Click' matches delegate 'RoutedEventHandler'.
I have tried several solutions as seen on stackoverflow and other sources but none has worked.
I'm new to C# programming, any help will be appreciated.
private string[,] LongRunningTask()
{
workSheetName = getWorkSheetName();
var sourceFile = OpenExcelFile(filePath);
var sourceWorkSheet = GetWorkSheet(sourceFile.Item1, sourceFile.Item2, workSheetName); //instantiating the object.
var doc_Max = GetDocRow_Col(sourceWorkSheet.Item1);
var maxRow_Col = GetMaxRow_Col(sourceWorkSheet.Item1, doc_Max.Item1, doc_Max.Item2);
int maxRowCount = maxRow_Col.Item1;
int maxColCount = maxRow_Col.Item2;
WriteLine("Last column with content is Row {0} ", maxRowCount);
WriteLine("Last column with content is Column {0} ", maxColCount);
var getItemsResult = getItems(sourceWorkSheet.Item1, maxRow_Col);
string[,] itemsArr = getItemsResult;
Bindng2DArrayToListview2(listview, itemsArr, maxColCount);
//enableItems();
GarbageCollector(sourceWorkSheet.Item1, sourceWorkSheet.Item2, sourceWorkSheet.Item3, sourceWorkSheet.Item4);
//searchButton.Click += (sender2, e2) => { searchButton_Click(sender2, e2, itemsArr); };
return itemsArr;
}
private async void StartTask()
{
this.progressLabel.Content = "Getting Sheets..";
try
{
await Task.Run(() => LongRunningTask());
}
catch(Exception e)
{
MessageBox.Show(e.ToString());
}
this.progressLabel.Content = "Done";
}

You could put the result of LongRunningTask into a field on the class (which I assume is the Window itself), then just access that field from searchButton_Click.
For example...
public partial class TheWindow : Window
{
private string[,] LongRunningTask()
{
// Your LongRunningTask implementation.
}
private async Task StartTask()
{
progressLabel.Content = "Getting Sheets...";
try
{
_itemsArr = await Task.Run(() => LongRunningTask());
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
progressLabel.Content = "Done!";
}
private void searchButton_Click(object sender, RoutedEventArgs e)
{
if (_itemsArr == null)
{
// The field is null for some reason. You'll have to decide what to do in this case, but
// naturally you can't use it if it's null.
return;
}
// Do the search using the field _itemsArr.
}
private string[,] _itemsArr = null;
}

Related

How can I print a pdf document from Xamarin.Forms UWP?

I have a Xamarin.Forms application that supports only UWP. I cannot find a way to print a pdf document. Whatever I have seen on the web, for some reason doesn't work for me. E.g. I tried
https://www.syncfusion.com/kb/8767/how-to-print-pdf-documents-in-xamarin-forms-platform
It lets me print, but the preview in the print dialog never shows up, and the progress indicator just keeps rotating forever.
I also tried http://zawayasoft.com/2018/03/13/uwp-print-pdf-files-silently-without-print-dialog/
This gives me errors that I cannot fix.
So I wonder if somebody can suggest something else that would actually work. Maybe something newer than what I have tried (I use VS 2017). Printing without the printing dialog would be preferable.
Thank you in advance.
I used a very dirty hack to do that!
What I had to do was to try to print the image version of the pdf (I did the conversion in backend) and then used the following DependencyInjection:
Inside my Print class in UWP project:
class Print : IPrint
{
void IPrint.Print(byte[] content)
{
Print_UWP printing = new Print_UWP();
printing.PrintUWpAsync(content);
}
}
and the class responsible for printing in uwp:
public class Print_UWP
{
PrintManager printmgr = PrintManager.GetForCurrentView();
PrintDocument PrintDoc = null;
PrintDocument printDoc;
PrintTask Task = null;
Windows.UI.Xaml.Controls.Image ViewToPrint = new Windows.UI.Xaml.Controls.Image();
public Print_UWP()
{
printmgr.PrintTaskRequested += Printmgr_PrintTaskRequested;
}
public async void PrintUWpAsync(byte[] imageData)
{
int i = 0;
while (i < 5)
{
try
{
BitmapImage biSource = new BitmapImage();
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
await stream.WriteAsync(imageData.AsBuffer());
stream.Seek(0);
await biSource.SetSourceAsync(stream);
}
ViewToPrint.Source = biSource;
if (PrintDoc != null)
{
printDoc.GetPreviewPage -= PrintDoc_GetPreviewPage;
printDoc.Paginate -= PrintDoc_Paginate;
printDoc.AddPages -= PrintDoc_AddPages;
}
this.printDoc = new PrintDocument();
try
{
printDoc.GetPreviewPage += PrintDoc_GetPreviewPage;
printDoc.Paginate += PrintDoc_Paginate;
printDoc.AddPages += PrintDoc_AddPages;
bool showprint = await PrintManager.ShowPrintUIAsync();
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
// printmgr = null;
// printDoc = null;
// Task = null;
PrintDoc = null;
GC.Collect();
printmgr.PrintTaskRequested -= Printmgr_PrintTaskRequested;
break;
}
catch (Exception e)
{
i++;
}
}
}
private void Printmgr_PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
var deff = args.Request.GetDeferral();
Task = args.Request.CreatePrintTask("Invoice", OnPrintTaskSourceRequested);
deff.Complete();
}
async void OnPrintTaskSourceRequested(PrintTaskSourceRequestedArgs args)
{
var def = args.GetDeferral();
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
args.SetSource(printDoc.DocumentSource);
});
def.Complete();
}
private void PrintDoc_AddPages(object sender, AddPagesEventArgs e)
{
printDoc.AddPage(ViewToPrint);
printDoc.AddPagesComplete();
}
private void PrintDoc_Paginate(object sender, PaginateEventArgs e)
{
PrintTaskOptions opt = Task.Options;
printDoc.SetPreviewPageCount(1, PreviewPageCountType.Final);
}
private void PrintDoc_GetPreviewPage(object sender, GetPreviewPageEventArgs e)
{
printDoc.SetPreviewPage(e.PageNumber, ViewToPrint);
}
}
Please note that this is not a perfect solution and sometimes it crashes without actually being able to trace the exception (which is really strange) so I am sure there must be better answers even though it does the job.

Why do you close the app when I change the page?

I have two List <>.
List<Musei> ListMusei;
List<Regioni> reg;
the object "Musei" has the property "Paese", while the object "Regioni" has the property "NomeProvincia".
The List "reg" is inserted in a ListView, and when pressed on an item, this method is invoked:
private void Listviewcitt_ItemClick(object sender, ItemClickEventArgs e)
{
var result = ((Regioni)e.ClickedItem).NomeProvincia.ToString();
var filtro = ListMusei.Where(x => x.Paese.Equals(result));
try
{
Frame.Navigate(typeof(PageAroundMe), filtro);
}
catch(Exception)
{
}
}
application where I always closes. I thought there was some problem in the "AroundMe", and then paste the code here:
In Page AroundMe I do this:
List<Musei> ListMusei;
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
ListMusei = (List<Musei>) e.Parameter;
List<Pushpin> push = new List<Pushpin>();
foreach (Musei SingoloMuseo in ListMusei)
{
Pushpin Pushpin pushpin1 = new ();
GeoPoint posizioneP;
try
{
MapLocationFinderResult result = await MapLocationFinder.FindLocationsAsync (SingoloMuseo.Indirizzo, null);
posizioneP result.Locations.FirstOrDefault = ().Point;
pushpin1.Name = SingoloMuseo.NomeMuseo;
pushpin1.Location = posizioneP;
push.Add (pushpin1);
}
catch (Exception)
{
continue;
}
}
Where is the problem? I can not even figure out where I will close
You can pass the parameter like
Frame.Navigate(typeof(PageAroundMe), filtro.ToList());
The invalid cast exception occurs because you are trying to cast IEnumerable type to List.

Display the current variable value while looping

private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
string IDs = ID.Text;
string[] eachIDs = Regex.Split(IDs, "\n");
foreach (var eachID in eachIDs)
{
getContent(eachID);
titleBox.Text = "Done";
}
}
private void getContent(string value)
{
label1.Text = value;
Thread.Sleep(5000);
}
I will give 4 id's as Input say "IDNUMBER01, IDNUMBER02, IDNUMBER03, IDNUMBER04" each in a new line in Rich Text Box.
The code splits them successfully. I want to show the Value of the ID being used in the current loop in a Label Text.
Problem with my code is it shows only the last ID which goes through the loop.
Probably your UI freezing and you can't see the changes.Try this, use async/await feature:
private async void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
string IDs = ID.Text;
string[] eachIDs = Regex.Split(IDs, "\n");
foreach (var eachID in eachIDs)
{
await getContent(eachID);
titleBox.Text = "Done";
}
}
private async Task getContent(string value)
{
label1.Text = value;
await Task.Delay(5000);
}
This is because the UI is only Updated after the execution of this code, since they are executing in the same thread. You will need to open a thread, run this code, and call the dispatcher (or the Control.BeginInvoke if this app is Winforms) to update the UI.
EDIT
Try this:
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
string IDs = ID.Text;
new System.Threading.Thread(() =>
{
string[] eachIDs = Regex.Split(IDs, "\n");
foreach (var eachID in eachIDs)
{
getContent(eachID);
titleBox.BeginInvoke((Action) delegate { titleBox.Text = "Done"; });
}
}).Start();
}
private void getContent(string value)
{
label1.BeginInvoke((Action) delegate { label1.Text = value; });
Thread.Sleep(5000);
}
In your example, you'd be better using a timer to display your value text. You're only seeing the last ID because the loop is executing very quickly, and using Thread.Sleep within the foreach isn't going to fly.
You could use Application.DoEvents() before the Thread.Sleep, but a timer is still your better option ... imho.

No overload for 'method' matches delegate 'delegate'

This is just a part of the code
A few lines down I'm trying to convert an Int to double. But the fact that the double is an array makes it hard...
I need to include "i" like I did in the previous function, but it wont work, and I get the following error;
No overload for 'webKoordx_OpenReadComplete' matches delegate 'System.Net.OpenReadCompletedEventHandler'
If you know any solution, or is able to see something I've missed, please help me!
private void getKoord(int i)
{
string stringKoX = "http://media.vgy.se/kristoferpk/spots/" + i + "/koordinatx.html";
string stringKoY = "http://media.vgy.se/kristoferpk/spots/" + i + "/koordinaty.html";
var webKoordx = new WebClient();
webKoordx.OpenReadAsync(new Uri(stringKoX));
webKoordx.OpenReadCompleted += new OpenReadCompletedEventHandler(webKoordx_OpenReadComplete);
var webKoordy = new WebClient();
webKoordy.OpenReadAsync(new Uri(stringKoY));
webKoordy.OpenReadCompleted += new OpenReadCompletedEventHandler(webKoordy_OpenReadComplete);
}
void webKoordx_OpenReadComplete(object sender, OpenReadCompletedEventArgs e, int i)//<<-----
{
try
{
using (var reader = new StreamReader(e.Result))
{
koordx = reader.ReadToEnd();
koordx_d[i] = Convert.ToDouble(koordx);
}
}
catch
{
MessageBox.Show("Kan ej ansluta");
MessageBox.Show("Kontrollera din anslutning");
}
}
void webKoordy_OpenReadComplete(object sender, OpenReadCompletedEventArgs e)//<<-----
{
try
{
using (var reader = new StreamReader(e.Result))
{
koordy = reader.ReadToEnd();
koordy_d[i] = Convert.ToDouble(koordy);
}
}
catch
{
MessageBox.Show("Kan ej ansluta");
MessageBox.Show("Kontrollera din anslutning");
}
}
You cannot pass extra information to an event handler like that.
Instead, you can add a lambda expression that handles the event and passes your extra information from its closure:
webKoordx.OpenReadCompleted += (sender, e) => MyMethod(e.Result, i);

Problems submitting DataGridView changes with Linq-to-SQL

I'm trying to implement database value edition through a DataGridView control but honestly I'm having a hard time trying to accomplish that. I'm basically using LINQ-to-SQL classes and events, the following being the most significant snippets:
var data = from q in data.FOOBARS
select new
{
ID = q.FOOBAR_ID,
LOREM = q.FOOBAR_LOREM,
IPSUM = q.FOOBAR_IPSUM
};
DataGridView grid = new DataGridView();
grid.DataSource = data;
// grid EVENTS
private void grid_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
this.grid.CurrentCell.ReadOnly = false;
this.grid.BeginEdit(true);
}
private void grid_CellLeave(object sender, DataGridViewCellEventArgs e)
{
if (this.grid.CurrentCell.IsInEditMode)
{
// METHOD CALL
this.SetVariableValue(this.grid.CurrentRow.Cells["ID"].Value.ToString(), this.grid.CurrentCell.OwningColumn.Name, this.grid.CurrentCell.FormattedValue.ToString(), this.grid.CurrentCell.EditedFormattedValue.ToString());
}
this.grid.CommitEdit(DataGridViewDataErrorContexts.Commit);
this.grid.EndEdit();
}
// METHOD IMPL
private void SetVariableValue(string id, string type, string current, string edited)
{
try
{
if (current != edited)
{
using (FOOBARDataClassesDataContext data = new FOOBARDataClassesDataContext(this.BuildConnection()))
{
data.ExecuteCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
switch (type)
{
case "LOREM":
var currentLorem = data.FOOBARS.SingleOrDefault(v => v.FOOBAR_ID == Convert.ToInt32(id)).FOOBAR_LOREM;
currentLorem = edited;
data.SubmitChanges(ConflictMode.ContinueOnConflict);
break;
case "IPSUM":
var currentIpsum = data.FOOBARS.SingleOrDefault(v => v.FOOBAR_ID == Convert.ToInt32(id)).FOOBAR_IPSUM;
currentIpsum = edited;
data.SubmitChanges(ConflictMode.ContinueOnConflict);
break;
default:
break;
}
data.Refresh(RefreshMode.OverwriteCurrentValues);
}
}
}
catch (Exception error)
{
if (logger.IsErrorEnabled) logger.Error(error.Message);
}
}
Debugging looks good, objects are actually being updated but for some reason changes are neither being submitted nor updated.
Any help would be certainly appreciated. Thanks much you guys in advance!
For some reason this does NOT WORK:
var currentLorem = data.FOOBARS.SingleOrDefault(v => v.FOOBAR_ID == Convert.ToInt32(id)).FOOBAR_LOREM;
currentLorem = edited;
data.SubmitChanges(ConflictMode.ContinueOnConflict);
But this DOES (notice the changes in lines 1 and 2, FOOBAR_LOREM attribute):
var currentLorem = data.FOOBARS.SingleOrDefault(v => v.FOOBAR_ID == Convert.ToInt32(id));
currentLorem.FOOBAR_LOREM = edited;
data.SubmitChanges(ConflictMode.ContinueOnConflict);

Categories