blah blah blah is here! blah blah » Close

up1down
link

Hey,

  • I have a string value (tmpfile) in my Login Form, How can I fetch it's value into my From2????

  • string tmpfile="";
    public void Button1_click()
    {
    tmpfile += Form1.Paths.logpath + comboBox1.Text + ".tmp";
    }


    Another thing......
  • How can I fetch the filename from a ".tmp" file when I know that my file is created in V:\*.tmp ????


  • If any tmp file exists in the path, then I wanted to compare All text values in my comboBox with the filename which is fetched by search for *.tmp
    for (int x = 0; x < comboBox1.Items.Count; x++)
    {
    string User = Path.GetFileNameWithoutExtension(Form1.Paths.logpath + comboBox1.Items[x].ToString() + ".tmp");
    if (comboBox1.Items.Contains(User))

    Does not works..... value of User is "System.Data.DataRowView" whereas it should be the Text value at the Item's IndexValue.

    Edit: What really I need "First" is that
    In my Login form:
    Before a user can login (Login_Load event), I need to check that IF any file (*.tmp) in Form1.Path.logpath matches with any text vlaue of comboBox1. Then a popup can be displayed "Another user (username) is already online, please wait".

    last answered one year ago

    11 answers

    up1down
    link

    Assuming you won't be closing the Login form - just hiding it - then I'd change tmpfile from a private instance field to an internal static field. Form2 should then be able to access it without needing a reference to the Login form (Login.tmpfile or whatever it is).

    On the second point, is it something like this that you're looking for ?

    string path = "V:\\";
    string[] tmpFiles = Directory.GetFiles(path, "*.tmp");
    for (int i = 0; i < tmpFiles.Length; i++)
    {
    tmpFiles[i] = Path.GetFileNameWithoutExtension(tmpFiles[i]).ToLower();
    }
    List<string> foundFiles = new List<string>();
    for (int i = 0; i < comboBox1.Items.Count; i++)
    {
    string fileName = comboBox1.Items[i].ToString();
    for (int j = 0; j < tmpFiles.Length; j++)
    {
    if (fileName.ToLower() == tmpFiles[j]) foundFiles.Add(fileName);
    }
    }
    if (foundFiles.Count == 0)
    {
    MessageBox.Show("No matches were found");
    }
    else
    {
    MessageBox.Show("The following matches were found: \r\n\r\n" + String.Join("\r\n", foundFiles.ToArray()));
    }

    gsvirdi
    412

    Ur suggestion was best that I can create a Public static Path { public const string logpath = "V:\\" } If I need to change the path then I have to do it in One place only. so in Login form I'm calling this "logpath" as >>>Form1.Paths.logpath<<<. At present I'm closing the login form bcoz Form2 is displayed after successful login. And in form closing event I'm trying to fetch this "tmpfile" value so that I can delete this file which is created from "Login" form.

    gsvirdi
    412

    Form closing event of Form2... trying to fetch this "tmpfile" value

    up1down
    link

    OK, if you're closing the Login form, then I'd leave the tmpfile declaration as it is but add an internal instance field to Form2:

    internal string tmpfile = "";

    When you open Form2 from the Login form, I'd now set this field:
    // something like this
    Form2 f2 = new Form2();
    f2.tmpfile = this.tmpfile;
    f2.Show();
    this.Close();

    The 'tmpfile' field will now be available to Form2's FormClosing eventhandler.

    If you only want one user to be online at a time, then the code in my previous answer will need modifying as follows:
    private Login_Load(object sender, EventArgs e)
    {
    string[] tmpFiles = Directory.GetFiles(Form1.Path.logpath , "*.tmp");
    for (int i = 0; i < tmpFiles.Length; i++)
    {
    tmpFiles[i] = Path.GetFileNameWithoutExtension(tmpFiles[i]).ToLower();
    }

    for (int i = 0; i < comboBox1.Items.Count; i++)
    {
    string fileName = comboBox1.Items[i].ToString();
    for (int j = 0; j < tmpFiles.Length; j++)
    {
    if (fileName.ToLower() == tmpFiles[j])
    {
    MessageBox.Show(String.Format("Another user ({0}) is already online, please wait", fileName));
    this.Close();
    return;
    }
    }
    }
    }

    gsvirdi
    412

    I'm at home and it's 11:30pm here (almost midnight), I'm not having the code to test. But something makes me feel that this is the solution I was looking for. So I'll thank u a million (in advance) and will get back to u after 11 hours from now :)

    up1down
    link

    just out of curiosity, is this a better (more efficient or more standard) than just passing the variable/object to the form in the form load event?

    ie

    Form2 frm = new Form2(tmpfiles);


    then on form2

    Private Form2(string[] tmpfiles)
    {
    //...
    }

    gsvirdi
    412

    A point here......

    vulpes
    17279

    I thought about passing tmpfile via the constructor which, as you say, is often suggested for this type of problem but then I thought he'll need to add a new field anyway and if he's calling Form2's constructor from somewhere else as well then it'll mess that up. So I settled on making the field internal rather than private and setting it directly from the Login form. No strong preference either way though :)

    up0down
    link

    Got the Prob in line ......
    string fileName = comboBox1.Items[i].ToString();

    value of fileName is "System.Data.DataRowView" .............

    So when we're trying to compare if (fileName.ToLower() == tmpFiles[j])... then the answer is never true bcoz the value of fileName is coming wrong.

    I think this is bcoz comboBox.Items is being fetched from an Access files's Table by using OleDB thing like this:

    OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" + filename + ";Jet OLEDB:Database Password=pASSord");
    conn.Open();
    var comm = new OleDbCommand("SELECT users FROM [user]", conn);
    var adapter = new OleDbDataAdapter(comm);
    DataSet DS = new DataSet();
    adapter.Fill(DS, "user");
    comboBox1.DataSource = DS.Tables[0];
    comboBox1.DisplayMember = "users";
    comboBox1.ValueMember = "users";

    But all the names in the mdb file's Table are vissible nicely in the comboBox's dropdown list...... strange!!!?

    Changing string fileName = comboBox1.Text; displays the Name (text) properly.

    up0down
    link

    Hmm, I think I can see now what the problem is :)

    When you bind to a DataTable, a DataRowView is created behind the scenes to represent each item in the combobox. This DataRowView contains the column to be displayed.

    So try replacing:

    string fileName = comboBox1.Items[i].ToString();

    with:
    DataRowView drv = (DataRowView)comboBox1.Items[i];
    string fileName = drv["users"].ToString();

    up0down
    link

    Bullseye Maaaaaan!!!!!!!!

    Thx a millions for this help. U helped me create a wonderful feature.

    But now the only prob is that sometimes while closing the form.... the utility is not able to delete the tmpfile automatically bcoz it get's a warning that the file is being used by another user. I can add a try block for this one... but I'm thinking that I should call the value of tmpfile in main form (form1) also and then try to delete it. Just to make sure that the .tmp is removed so that another user can log in.

    But to fetch the username in Form1.... I think I have to call the value of below code in form1.

    .
    DataRowView drv = (DataRowView)comboBox1.Items[i];
    string fileName = drv["users"].ToString();


    :)

    vulpes
    17279

    Well, I'd have thought that you need to delete the .tmp file when a user logs off. If this is always done by simply closing the application, then it should go in the startup form's FormClosed event handler. If that's where you've got it just now, then I don 't understand why you sometimes get the warning about it being used by another user - if that were the case, then how could the present user have logged on in the first place?

    up0down
    link

    Okie letme try to recreate the flow diagram:
    There are three forms, Form1, LoginForm, and Editables.

  • Form1 = main form with Readonly DGV

  • LoginForm = uses OleDb to fetch values of the dropDownList, checks if any username.tmp exits or not, creates a username.tmp file on Login

  • Editables = Contains writable DGV, saves DGV to xml, Logout (delete the tmp file) on Formclosing.

  • Form1 remains opened all the time, Editables form just overlaps the Form1, and on logout... Editables form is closed and Form1 is displayed bcoz its always there.


  • So as now we created the username.tmp file, the LoginForm closes, and Editables form is opened. But on closing the editables form, the tmp file should be deleted, and sometimes it gets deleted also.

    EDIT:
    But I just did some troubleshooting and noticed that if user2 tries to login, the Message to wait is displayed perfectly. So I think maybe this 2nd user is the one who is using that tmp file. I think so bcoz...

    I saw that when user2 saw that user1 is logged in, and he closed the application. Then the tmp file got deleted properly on Logout of User1. But if User2 had not closed this application completly, then the Logout of User1 shows that error of file being used.

    Hope this clears the clouds for u.....

    up0down
    link

    Well, I'm clearer than I was ;)

    So, let me just go through it in my simple-minded way which sometimes helps.

    Suppose the application is being run on the network for the very first time and so there are no *.tmp files on the shared drive.

    User1 then logs in and user1.tmp is created. He then logs out and the FormClosing eventhandler on the Editables form ensures that user1.tmp is deleted.

    After that user2 logs in and user2.tmp is created. However, whilst user2 is still working on the application user1 tries to log in again but is told to wait because user2.tmp still exists.

    So, if I've understood it correctly, it shouldn't be possible for more than one *.tmp file to exist at an given moment.

    Now, it can be difficult to debug this sort of scheme because, if an uncaught exception is thrown and the application bombs out then, when you restart it, a user may still appear to be logged in (because his .tmp file wasn't deleted) when in fact he isn't!

    Similar problems can arise if there's a power cut or if the user turns off his machine without shutting down the application first.

    So, is it possible that you could be experiencing this sort of problem here?

    up0down
    link

    .

    up0down
    link

    :( Yup... u're right.

    I had seen that same thing when I was trying to play around with creating & deleting the username.tmp file! Bcoz as the application is not able to find the username.tmp ( value of fileName is "System.Data.DataRowView") ... due to this reason the username.tmp file is existing in the drive.

    To take care of these things I shall be deleting (*.tmp) files from the disk on Form1 closing event, or shall I delete (*.tmp) file when the file delete event (in logout) fails?

    What do u say?

    up0down
    link

    I'd put the code to ensure the .tmp file is deleted in Form1's FormClosed eventhandler.

    It might also be a good idea to allow for the possibility that an unhandled exception may occur and shutdown the application before you can delete the file. You can do this by making the following changes to your program.cs file:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    using System.Threading; // add this using directive

    namespace WindowsFormsApplication1 // or whatever it's called
    {
    static class Program
    {
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    // add these next two lines
    Application.ThreadException += Program_UIThreadException;
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    Application.Run(new Form1());
    }

    // add this handler
    static void Program_UIThreadException(object sender, ThreadExceptionEventArgs t)
    {
    MessageBox.Show("An unhandled exception has occurred. Application will be shut down");
    Application.Exit(); // closes all open forms and then application
    }
    }
    }

    Although you can try to continue after an unhandled exception, unless you want to give the user an opportunity to save data, it's usually best to terminate the application in case it's been left in an unstable state. I've therefore called Application.Exit() in the handler which will also ensure that the Form1_FormClosed event fires (and the .tmp file is therefore deleted) before the application is shut down.

    Feedback