Can I invoke another form 's task [duplicate] - c#

This question already has answers here:
How to call function from another form
(5 answers)
Closed 5 years ago.
in form1 , there are two functions , one for a button 's click event
private void bQuery_Click(object sender, EventArgs e)
{
string sPrefix = tbPrefix.Text.Trim();
QueryAll(sPrefix);
}
another one is a task
async Task QueryAll(string sPrefix)
{
}
now I need invoke form1 's task in form2 certain function , such as
string prefix = "abc";
frm = new form1();
frm.ShowDialog();
frm.Dispose();
frm.QueryAll(sPrefix);
I know this statement
frm.QueryAll(sPrefix);
can not compile , just to show what I want to do , anyone knows how to call this task "QueryAll" ? thanks for your help

it will be task
public Task QueryAll(string sPrefix)
{
return Task.Run(() =>
{
//code here
var foo = sPrefix;
});
}
then
frm = new form1();
frm.QueryAll(sPrefix).GetAwaiter().GetResult();

Related

How to write to a textbox that is in another Form? [duplicate]

This question already has answers here:
Passing a value from one form to another form
(9 answers)
Writing to a textbox on a separate form (C#)
(4 answers)
Closed 5 years ago.
I have a .NET application which has 2 forms: inside Form1 there is all the application stuff, while inside LogForm there is only a readonly textbox. I want to print some text to this textbox inside LogForm from Form1, while Form1 is performing all the work.
I open my LogForm via the
LogForm logForm = new LogForm();
logForm.Show();
But then? How can I do that?
You must have the reference to this TextBox.
Put your access modifier to public in your visual studio form designer and access your TextBox by logForm1.YourTextBox.Text += "new line \r\n";
You can make your LogForm to accept Arguments on initialization:
string ValueFromForm1 = null;
public LogForm(string input)
{
ValueFromForm1 = input;
}
The on Form_Load set the value of textbox:
TextBox1.Text = ValueFromForm1 ;
Create a public variable in Form1 and call in LogForm
Form 1
public static string logformtext;
logformtext="Required text"; //Value which you want to pass to LogForm
LogForm
TextBox1.Text=Form1.logformtext;
Either you can set the text in the constructor of LogForm:
public LogForm(string text)
{
InitializeComponent();
textBox1.Text = text;
}
or you can set the modifier of the TextBox to Internal (or even Public) on the Designer and then access it from Form1 like this:
logForm.textBox1.Text = "Your text";
But keep in mind that while your program is working, the text will not show up on your LogForm, unless you repaint it, or use a BackgroundWorker to have the work be done in a different thread.

cross-thread opertion in combobox in c# [duplicate]

This question already has answers here:
How do I update the GUI from another thread?
(47 answers)
Closed 8 years ago.
catch (Exception ex)\\error
{
clsLogs.LogError("Error: " + ex.Message + this.Name + " || ImportData");
result = false;
}
;Cross-thread operation not valid: Control 'cmbDeviceName' accessed from a thread other than the thread it was created on
You can do it like this using Invoke:
this.Invoke((MethodInvoker)delegate()
{
//// your code
});
class YourForm : Form
{
private SynchronizationContext synchronizationContext ;
public YourForm()
{
this.synchronizationContext = SynchronizationContext.Current;
//the rest of your code
}
}
and then, when you need to do some thread-unsafe form actualizations you should use something like this:
synchronizationContext.Send(new SendOrPostCallback(
delegate(object state)
{
textBoxOut.Text = "New text";
}
), null);
source codeproject

custom single line messagebox [duplicate]

This question already has answers here:
How to create a custom MessageBox?
(4 answers)
Closed 9 years ago.
I'm trying to make a custom message box for my application. The problem is, I want to code it in a way so that I can use it as regular message box.
MyCustomBox("My Message");
intead of doing
FormMessage frm = new FormMessage();
frm.message = "My Message";
frm.show();
How can I accomplish this? Thanks!
You can add a static method to FormMessage class
public static void ShowBox(string message)
{
using (FormMessage frm = new FormMessage())
{
frm.Message = message;
frm.ShowDialog();
}
}
And then
FormMessage.ShowBox("My Message");
Create the form with the appropriate controls, etc. Then add a static method to the class that handles all the messy bits - creating an instance (if necessary), setting properties, etc.
I wish I could write more on this, but it's pretty simple stuff. Just call MyCustomBox.ShowMessage() or whatever you call the static method.

Accessing string from another Form

Hello I have datagridview in form1 and through form1 I open form2 and through form2 I open form3 and string named vyber_ID_K placed in Form1 needs to be accessed in Form3 (I need to get its value in Form3)
this is placed on button click in form1
form2 a = new form2 ("Novy");
string vyber_IDK = (string)dataGridView1.CurrentRow.Cells["ID_K"].Value.ToString();
a.vyber_ID_K = vyber_IDK;
a.Show();
a.Closed += klient_Closed;
I would like to access vyber_ID_K in form 3, how it can be done? I tried to set public string vyber_ID_K in form2 and pass it similary to form3 but I get null. Am I doing it right? Is there any other better solution please?
Thanks in advance.
My step-by-step according to Servy:
button click in Form 1
Func vyberIDKGetter = () => dataGridView1.CurrentRow.Cells["ID_K"].Value.ToString();
try
{
form2 = new form2 ("Novy");
a.vyberIDKGetter = () => dataGridView1.CurrentRow.Cells["ID_K"].Value.ToString();
a.Show();
}
button click in form2
public Func vyberIDKGetter;
private void button1_Click(object sender, EventArgs e)
{
nova_platba b = new nova_platba("novy");
b.vyberIDKGetter();
b.Show();
b.Closed += klient_Closed;
}
In form3
Func<string> vyberIDKGetter = veberIDK;
string vyberIDK = vyberIDKGetter();
SqlCommand sc = new SqlCommand(#"
INSERT INTO kliplat (datum,text,castka,akce,subkey,priznak,rocnik)
VALUES (#datum,#text,#castka,#akce,#subkey,#priznak,#rocnik);
SELECT scope_identity();
", spojeni);
sc.Parameters.AddWithValue("#subkey", vyberIDK);
So the issue here is that the value that you want doesn't exist yet when you're constructing Form2, or even Form3 for that matter. It needs to have some means of accessing the data at some point in the future. We can get this behavior by leveraging delegates.
Rather than passing a string to Form2, when that form is constructed (since we don't know what the string will be yet) pass a Func<string>. That object will be a method that, when invoked, will provide a string that represents the needed value. Form1 can define it like this:
Func<string> vyberIDKGetter =
() => dataGridView1.CurrentRow.Cells["ID_K"].Value.ToString();
Then in Form3 when it's holding onto the function that was passed it can get the string out by simply invoking that delegate:
Func<string> vyberIDKGetter = [...];
string vyberIDK = vyberIDKGetter();
This approach to solving the problem is particularly adventageous in that Form3 doesn't need to know anything about Form1 or Form2. If there is some other caller that wants to use it they can provide their own delegate instead. If there is a developer handling the coding of each form they don't need to communicate all of the internal details of each form to each other, they can just handle the passing of this delegate and then be able to treat the caller/callee as a black box.
You have to make a public getter/setter around the string:
public string Vyber_ID_K
get
{
return vyber_ID_K;
}
set
{
vyber_ID_K = value
}
That you need a reference from Form 1 in Form 2, and from Form 2 in Form 3. So you can access
each Form.
You can't use a string as Referenced Parameter, becuase it is an immutable class. String C#
That is a really odd that you pass a parameter via the constructor
form2 a = new form2 ("Novy");
and in the same time you pass another parameter via the property
a.vyber_ID_K = vyber_IDK;
Why don't you instead pass all parameters via the constructor?
string vyber_IDK = (string)dataGridView1.CurrentRow.Cells["ID_K"].Value.ToString();
form2 a = new form2 ("Novy", vyber_IDK);
and in Form2
public class form2
{
private string Name { get; set; }
private int vyber_IDK { get; set; }
public form2( string Name, int vyber )
{
this.Name = Name;
this.vyber_IDK = vyber_IDK;
}
Then, passing anything to form3 from form2 works in the same way
form3 f = new form3( this.vyber_IDK );

C# OpenFileDialog Non-Modal possible

Is it possible to create/have a non-modal .net OpenFileDialog I have a UI element in the main dialog which always need to be available for the user to press.
No, OpenFileDialog and SaveFileDialog are both derived from FileDialog, which is inherently modal, so (as far as I know) there's no way of creating a non-modal version of either of them.
You can create a thread and have the thread host the OpenFileDialog. Example code is lacking any kind of synchronization but it works.
public partial class Form1 : Form
{
OFDThread ofdThread;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ofdThread = new OFDThread();
ofdThread.Show();
}
}
public class OFDThread
{
private Thread t;
private DialogResult result;
public OFDThread()
{
t = new Thread(new ParameterizedThreadStart(ShowOFD));
t.SetApartmentState(ApartmentState.STA);
}
public DialogResult DialogResult { get { return this.result; } }
public void Show()
{
t.Start(this);
}
private void ShowOFD(object o)
{
OpenFileDialog ofd = new OpenFileDialog();
result = ofd.ShowDialog();
}
}
With this code you could add something to fire an event in your UI thread (be careful with invoking!) to know when they're done. You can access the result of the dialog by
DialogResult a = ofdThread.DialogResult
from your UI thread.
I know I am a little late but you may create a new form, borderless, transparent or outside the display bounds and show the file dialog modding that window.
It is an old post but I spend 2 days reaching the result I want to present here ( with "context" and complete but simplified code )
#Joshua 's answer worked for me ( at last when I put true to .ConfigureAwait(true), see first code sample). Maybe I was able to write less lines based on the long article of MSDN Threading Model that I still need to read once again.
My context is WPF ( basic MVVM ) and I must choose a file in order to write some .CSV backup ( of a datagrid ). I need that the (member) function ChooseFileFromExtension() be asynchronous with a non-blocking FileDialog
class MainWindowExportToExcelCSV : ICommand
{
...
public async void Execute(object parameter)
{
var usr_ctrl = parameter as UserControl;
MyFileDialog fd = new MyFileDialog();
const bool WhenIComeBackIStillNeedToAccessUIObjectAndThusINeedToRetrieveMyOriginalUIContext = true;
string filename = await fd.ChooseFileFromExtension("CSV files (*.csv)|*.csv|All files (*.*)|*.*").ConfigureAwait(
WhenIComeBackIStillNeedToAccessUIObjectAndThusINeedToRetrieveMyOriginalUIContext);
Visual visual = (Visual)usr_ctrl.Content;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
{
//look for datagrid element
}
}
}
and the code for MyFileDialog class
using Microsoft.Win32;
...
class MyFileDialog
{
//https://msdn.microsoft.com/en-us/library/ms741870(v=vs.110).aspx
//Article on Threading Model
private delegate void OneArgStrDelegate(string str);
private void MyExternalDialog(string extensions)
{
SaveFileDialog fd = new SaveFileDialog();
fd.Filter = extensions;
fd.ShowDialog();
tcs.SetResult(fd.FileName);
}
private TaskCompletionSource<string> tcs;
public Task<string> ChooseFileFromExtension(string file_ext)
{
//Cf Puppet Task in Async in C#5.0 by Alex Davies
tcs = new TaskCompletionSource<string>();
OneArgStrDelegate fetcher = new OneArgStrDelegate(this.MyExternalDialog);
fetcher.BeginInvoke(file_ext, null, null);
return tcs.Task;
}
}
The fetcher.BeginInvoke() launches (asynchronously) the SaveFileDialog ShowDialog() in another thread so that the main UI Thread / Window (...++) are neither blocked nor disabled as they would have been with a simple direct call to ShowDialog(). TaskCompletionSource<string> tcs is not an WPF UI Object so its access by another "single" thread is OK.
It is still a field that I need to study further. I feel there is no "ultimate" documentation/book on the subject ( maybe should have a second look to books like the one from Stephen Cleary again). This code should be improved at least with topic covered on c-sharp-asynchronous-call-without-endinvoke
It works with the FileDialog of namespace Microsoft.Win32

Categories

Resources