2014-10-31 90 views
0

無法弄清楚如何從線程更新文本框。有任何想法嗎?對不起,如果變量名稱和字符串是挪威語。如果有問題可以修復。 問題主要是我無法訪問線程內的文本框。我是否創建單獨的線程,一個用於服務器,另一個用於更新txtbox?在那種情況下,我該怎麼做?無法使用線程打印文本框中的文本。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.Net; 
using System.Net.Sockets; 
using System.Threading; 
using System.Threading.Tasks; 
namespace SentralGUI.Pages 
{ 
    /// <summary> 
    /// Interaction logic for Server.xaml 
    /// </summary> 




public partial class Server : UserControl 
{ 
    public class Bruker 
    { 
     public string BrukerID { get; set; } 
     public string Passord { get; set; } 
     public string Forbruk { get; set; } 

    } 
    public class ServerStart 
    { 
     public List<Bruker> brukerList { get; set; } 
     int n = 3; 
     int n_login = 5; 
     int recv, recvID, recvP; 
     byte[] data = new byte[1024]; 
     string mottattKundeID; 
     string mottattPassord; 
     string consoleText = ""; 


     public string TxtUt() 
     { 

      return consoleText; 

     } 

     public void Start() 
     { 
      Socket lytteSokkel = new Socket(
             AddressFamily.InterNetwork, 
             SocketType.Stream, 
             ProtocolType.Tcp); 

      IPEndPoint serverEP = new IPEndPoint(
             IPAddress.Parse("127.0.0.1"), 9050); 

      lytteSokkel.Bind(serverEP); 
      lytteSokkel.Listen(10); 



      while (n-- > 0) 
      { 
       consoleText = "venter på en klient..."; 


       Socket kommSokkel = lytteSokkel.Accept(); // blokkerende 
       // metode 

       IPEndPoint klientEP = 
            (IPEndPoint)kommSokkel.RemoteEndPoint; 
       consoleText = "Har forbindelse med {0} på port {1}" + 
              klientEP.Address + serverEP.Port; 


       string startup = "Login med kunde ID og passord:"; 
       data = Encoding.ASCII.GetBytes(startup); 
       kommSokkel.Send(data, data.Length, SocketFlags.None); 

       while (n_login > 0) 
       { 
        kommSokkel.Send(Encoding.ASCII.GetBytes("\nBruker ID: ")); 

        data = new byte[1024]; 
        recvID = kommSokkel.Receive(data); 
        if (recvID == 0) 
         break; 

        mottattKundeID = 
             Encoding.ASCII.GetString(data, 0, recvID);//her kommer input fra klient: BrukerID 

        kommSokkel.Send(Encoding.ASCII.GetBytes("Passord: ")); 

        recvP = kommSokkel.Receive(data); 
        mottattPassord = Encoding.ASCII.GetString(data, 0, recvP);//her kommer input fra klient: Passord 





        bool godkjent_Login = Login(mottattKundeID, mottattPassord, brukerList); 



        if (godkjent_Login) 
        { 
         kommSokkel.Send(Encoding.ASCII.GetBytes("\nGodkjent innlogging! Trykk en tast for å få ditt forbruk.\n")); 
         string kundeForbruk = SkrivUtForbruk(mottattKundeID, brukerList); 
         kommSokkel.Send(Encoding.ASCII.GetBytes(kundeForbruk)); 
         n_login = 0; 
        } 
        else kommSokkel.Send(Encoding.ASCII.GetBytes("\nBruker ID eller passord er feil! Prøv igjen.")); 
       } 
       consoleText = "Forbindelsen med {0} er brutt " + 
                 klientEP.Address; 

       n_login = 5; 
       kommSokkel.Close(); 
      } 

      lytteSokkel.Close(); 


     } 
     private static string SkrivUtForbruk(string kundeID, List<Bruker> bruker) 
     { 
      string forbrukUT = ""; 
      foreach (Bruker kunde in bruker) 
      { 
       if (kunde.BrukerID.Contains(kundeID)) forbrukUT = kunde.Forbruk; 
      } 

      return forbrukUT; 
     } 
     private static bool Login(string id, string pass, List<Bruker> bl) 
     { 

      bool godkjent = false; 


      //var brukerLogin = new List<BrukerLogin>(); 
      //brukerLogin.Add(new BrukerLogin { BrukerIDInn = id , PassordInn = pass }); 
      foreach (Bruker kunde in bl) 
      { 
       if (kunde.BrukerID == id && kunde.Passord == pass) godkjent = true; 
      } 
      // Console.WriteLine(bl_godkjent); 
      //if (brukerID_godkjent) godkjent = true; 
      return godkjent; 

     } 


    } 



    public Server() 
    { 
     InitializeComponent(); 
     txtConsol.IsEnabled = false; 



    } 


    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     btnServerStart.IsEnabled = false; 

     var brukerList = new List<Bruker>(); 
     brukerList.Add(new Bruker { BrukerID = "13", Passord = "iamlorde", Forbruk = "6KW" }); 
     brukerList.Add(new Bruker { BrukerID = "14", Passord = "iamlorde", Forbruk = "5KW" }); 
     brukerList.Add(new Bruker { BrukerID = "15", Passord = "iamlorde", Forbruk = "63KW" }); 
     brukerList.Add(new Bruker { BrukerID = "16", Passord = "iamlorde", Forbruk = "71KW" }); 
     brukerList.Add(new Bruker { BrukerID = "17", Passord = "iamlorde", Forbruk = "1KW" }); 

     ServerStart objSTart = new ServerStart(); 
     Thread objTraad = new Thread(new ThreadStart(objSTart.Start)); 

     objTraad.Start(); 
     while (!objTraad.IsAlive) 
     { 
      Thread.Sleep(1000); 
      string txt_ut = objSTart.TxtUt(); 
      TxtUt(txt_ut); 
     } 



    } 
     public void TxtUt(string ct) 
     { 
      txtConsol.AppendText(ct); 

     } 
} 
} 
+0

你不能直接更新UI從另一個線程,我想在WPF中使用'Dispatcher.Invoke'。 – 2014-10-31 16:22:14

+0

txtConsol是一個UI控件?如果是這樣,那就不是。 – Paparazzi 2014-10-31 16:34:31

回答

1

在WPF中,您可以使用分派器從單獨的線程對UI項目進行更改。這是最基本的形式,你會使用:

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(()=>{ 
    yourTextBox.Text = // your value; 
    Console.WriteLine(yourTextBox.Text); 
})); 

如果由於某種原因你不能確定是否是UI線程或一個單獨的線程上,你可以使用Dispatcher.CheckAccess(),這將返回如果您在UI線程中則爲true,如果在單獨的線程中則爲false。

if (Application.Current.Dispatcher.CheckAccess()) { 

請注意,DispatcherPriority需要使用System.Windows.Threading命名空間。

+0

我以前的答案只適用於winforms ... @furkle有一個更好的答案。 – MikeH 2014-10-31 17:09:04

+0

@MikeH謝謝,只是不想讓任何人感到困惑。我相信在WPF中有這樣做的更好的方法,所以請隨時在這一個上面。 – furkle 2014-10-31 17:12:42

+0

沒問題,很高興你提起它。我沒有做太多的WPF,所以我不確定我能否提供更好的答案。我錯誤地認爲winform方法奏效。 – MikeH 2014-10-31 17:14:33

0

雖然運行在線程主線程不同的代碼,訪問UI控件應該被包裹在this.Invoke所有代碼(委託(){...})