2015-01-22 1 views
0

아래 내 창 (전체 화면)에 대한 전체 클래스를 연결합니다. 나는 내가 쟁점/염려/문제라고 생각하는 것을 논평 할 것이고, 후에 나는 내 의견을 목록 순서대로 설명 할 것이다. 가장 유용한 대답은 코드를 참조로 사용하여 나열된 질문에 대답하는 사람들입니다. 메인 윈도우 cs와 RowContainer 클래스 (간단한 관리 클래스)를 제공 할 것입니다. 여기 같은 행에서 행 및 모든 컨트롤 제거

내가 모든 행은 내가 행을 제거 할 때까지 이동해야하는 경우 나 확실하지 않다 간단하기 때문에이 방법 RemoveFromRowList을 표시 enter image description here

public partial class MainWindow : Window 
{ 
    public static DebugWindow debugWindow; 
    public static MainWindow mainWindow; 
    public static Dispatcher mainWindowDispacter; 

    private Object locker = new Object(); 
    public ConnectionHandle ConnectionHandler; 


    public RowContainer[] RowContents; 

    public MainWindow() 
    { 
     InitializeComponent(); 
     mainWindow = this; 
     mainWindowDispacter = this.Dispatcher; 
    } 

    public RowContainer RowExists(Client c) 
    { 
     if (RowContents == null) 
      return null; 
     foreach (RowContainer r in RowContents) 
     { 
      if (r.GetClient().getUID().Equals(c.getUID())) 
       return r; 
     } 
     return null; 
    } 
// ----------------1 -------------------- 
    public void RemoveFromRowList(RowContainer r) 
    { 
     List<RowContainer> l = new List<RowContainer>(); 
     List<int> usedList = new List<int>(); 
     int deleteRowNumber = r.rowNumber; 
     foreach (RowContainer rr in RowContents) 
     { 
      if (!r.Equals(rr)) 
      { 
       if (rr.rowNumber > deleteRowNumber) 
        rr.rowNumber--; 
       l.Add(rr); 
      } 
     } 
     RowContents = l.ToArray(); 
    } 
//----------------------- 2 ------------------- 
    public void AddToRowList(RowContainer r) 
    { 
     if (RowContents == null) 
     { 
      r.rowNumber = 1; 
      RowContents = new RowContainer[] { r }; 
      return; 
     } 
     List<RowContainer> l = new List<RowContainer>(); 
     List<int> usedList = new List<int>(); 
     foreach (RowContainer rr in RowContents) 
     { 
      l.Add(rr); 
      usedList.Add(rr.rowNumber); 
     } 
     Console.WriteLine(usedList.ToString()); 
     int? firstAvailable = Enumerable.Range(1, int.MaxValue) 
          .Except(usedList) 
          .FirstOrDefault(); 
     r.rowNumber = (int)firstAvailable; 
     l.Add(r); 
     RowContents = l.ToArray(); 
    } 

    private void onDebugLogClick(object sender, RoutedEventArgs e) 
    { 
     if (debugWindow == null) 
     { 
      debugWindow = new DebugWindow(); 
      debugWindow.Show(); 
     } 
     else 
     { 
      if (debugWindow.IsVisible) 
      { 
       debugWindow.Hide(); 
      } 
      else 
       debugWindow.Visibility = Visibility.Visible; 
     } 
    } 

    public BitmapImage ToImage(byte[] array) 
    { 
     using (var ms = new System.IO.MemoryStream(array)) 
     { 
      var image = new BitmapImage(); 
      image.BeginInit(); 
      image.CacheOption = BitmapCacheOption.OnLoad; 
      image.StreamSource = ms; 
      image.EndInit(); 
      return image; 
     } 
    } 
    // type 0 - image, 1 - status, 2 - OS, 3 - Idle, 4 - bitaccount 
    public void UpdateRowContainer(RowContainer r, int type) 
    { 
      switch (type) 
      { 
       case 0: 
        BitmapImage image = ToImage(r.Image); 
        System.Windows.Controls.Image uiImage = (System.Windows.Controls.Image)MyGrid.Children.Cast<UIElement>().First(e => Grid.GetRow(e) == r.rowNumber & Grid.GetColumn(e) == 0); 
        if (uiImage == null) 
        { 
        } 
        else 
        { 
         uiImage.Source = image; 
        } 
        break; 
       case 2: 
        Label OsLabel = (System.Windows.Controls.Label)MyGrid.Children.Cast<UIElement>().First(e => Grid.GetRow(e) == r.rowNumber & Grid.GetColumn(e) == 5); 
        OsLabel.Content = r.Os; 
        break; 
       case 3: 
        Label idleLabel = (System.Windows.Controls.Label)MyGrid.Children.Cast<UIElement>().First(e => Grid.GetRow(e) == r.rowNumber & Grid.GetColumn(e) == 3); 
        idleLabel.Content = r.idle; 
        break; 

     } 

    } 
// --------------------------- 3---------------------- 
    public void CreateClientRowContainer(Client c, byte[] imageBytes) 
    { 
      RowContainer newContainer = new RowContainer(c); 
      BitmapImage image = ToImage(imageBytes); 
      newContainer.Image = imageBytes; 
      Label cLabel = new Label(); 
      Label osLabel = new Label(); 
      Label stateLabel = new Label(); 
      Label bitAccountLabel = new Label(); 
      Label idleTimeLabel = new Label(); 
      osLabel.Content = "N/A"; 
      stateLabel.Content = "N/A"; 
      bitAccountLabel.Content = "N/A"; 
      idleTimeLabel.Content = "N/A"; 
      cLabel.Content = c.getClientIp(); 
      cLabel.SetValue(Grid.ColumnProperty, 1); 
      stateLabel.SetValue(Grid.ColumnProperty, 2); 
      idleTimeLabel.SetValue(Grid.ColumnProperty, 3); 
      bitAccountLabel.SetValue(Grid.ColumnProperty, 4); 
      osLabel.SetValue(Grid.ColumnProperty, 5); 
      int rowCount = this.MyGrid.RowDefinitions.Count; 
      this.MyGrid.RowDefinitions.Add(new RowDefinition()); 
      Style style = this.FindResource("LabelTemplate") as Style; 
      Style style2 = this.FindResource("OSTemplate") as Style; 
      cLabel.Style = style; 
      stateLabel.Style = style; 
      bitAccountLabel.Style = style; 
      idleTimeLabel.Style = style; 
      osLabel.Style = style2; 
      cLabel.SetValue(Grid.RowProperty, rowCount); 
      bitAccountLabel.SetValue(Grid.RowProperty, rowCount); 
      stateLabel.SetValue(Grid.RowProperty, rowCount); 
      idleTimeLabel.SetValue(Grid.RowProperty, rowCount); 
      osLabel.SetValue(Grid.RowProperty, rowCount); 
      System.Windows.Controls.Image imgIcon = new System.Windows.Controls.Image(); 
      imgIcon.Height = 150; 
      imgIcon.HorizontalAlignment = HorizontalAlignment.Center; 
      imgIcon.VerticalAlignment = VerticalAlignment.Top; 
      imgIcon.Source = image; 
      MyGrid.Children.Add(cLabel); 
      MyGrid.Children.Add(idleTimeLabel); 
      MyGrid.Children.Add(stateLabel); 
      MyGrid.Children.Add(bitAccountLabel); 
      MyGrid.Children.Add(osLabel); 
      ConnectionHandle.SendRequestInformation(c, 3); 
      imgIcon.SetValue(Grid.ColumnProperty, 0); 
      imgIcon.SetValue(Grid.RowProperty, rowCount); 
      MyGrid.Children.Add(imgIcon); 
      AddToRowList(newContainer); 

    } 
// -------------------- 4 --------------------- 
    public void RemoveClientGrid(Client c) 
    { 
     RowContainer con = RowExists(c); 
     if (con == null) 
      return; 
     if (MyGrid.RowDefinitions.Count < con.rowNumber) 
     { 
      RemoveFromRowList(con); 
      return; 
     } 
      Console.WriteLine("Removing row: " + con.rowNumber); 
      Console.WriteLine("Total rows: " + MyGrid.RowDefinitions.Count); 
      RowDefinitionCollection defs = MyGrid.RowDefinitions; 
      foreach (UIElement control in MyGrid.Children) 
      { 
       if (Grid.GetRow(control) == con.rowNumber) 
       { 
        MyGrid.Children.Remove(control); 
       } 
      } 
      defs.RemoveAt(con.rowNumber); 
      RemoveFromRowList(con); 

    } 

    protected override void OnClosing(CancelEventArgs e) 
    { 
     if (debugWindow != null) 
      debugWindow.Close(); 
     Environment.Exit(Environment.ExitCode); 
     base.OnClosing(e); 
    } 

    private void onServerStartClick(object sender, RoutedEventArgs e) 
    { 
     if (ConnectionHandler == null) 
     { 
      ConnectionHandler = new ConnectionHandle(); 
     } 
     else 
     { 
      MessageBox.Show("Server Has Already Started!"); 
     } 
    } 

    private Client GetRowClient(int row) 
    { 
     foreach(RowContainer r in RowContents) { 
      if (r.rowNumber == row) 
       return r.client; 
     } 
     return null; 
    } 


    private void onRefreshMenuClick(object sender, RoutedEventArgs e) 
    { 
     MenuItem mi = sender as MenuItem; 
     if (mi != null) 
     { 
      ContextMenu cm = mi.CommandParameter as ContextMenu; 
      if (cm != null) 
      { 
       Grid g = cm.PlacementTarget as Grid; 
       if (g != null) 
       { 

        var p = Mouse.GetPosition(g); 

        int row = 0; 
        int col = 0; 
        double accumulatedHeight = 0.0; 
        double accumulatedWidth = 0.0; 

        // calc row mouse was over 
        foreach (var rowDefinition in g.RowDefinitions) 
        { 
         accumulatedHeight += rowDefinition.ActualHeight; 
         if (accumulatedHeight >= p.Y) 
          break; 
         row++; 
        } 
        Client c = GetRowClient(row); 
        if (c != null) 
        { 
         ConnectionHandle.SendRequestInformation(c, 1); 
         ConnectionHandle.SendRequestInformation(c, 4); 
        } 
        else 
         if (debugWindow != null) 
          debugWindow.LogTextBox.AppendText("Unable to find client!"); 
       } 
      } 
     } 
    } 

    private void onDisconnectClicked(object sender, RoutedEventArgs e) 
    { 
     MenuItem mi = sender as MenuItem; 
     if (mi != null) 
     { 
      ContextMenu cm = mi.CommandParameter as ContextMenu; 
      if (cm != null) 
      { 
       Grid g = cm.PlacementTarget as Grid; 
       if (g != null) 
       { 

        var p = Mouse.GetPosition(g); 

        int row = 0; 
        int col = 0; 
        double accumulatedHeight = 0.0; 
        double accumulatedWidth = 0.0; 

        // calc row mouse was over 
        foreach (var rowDefinition in g.RowDefinitions) 
        { 
         accumulatedHeight += rowDefinition.ActualHeight; 
         if (accumulatedHeight >= p.Y) 
          break; 
         row++; 
        } 
        Client c = GetRowClient(row); 
        if (c != null) 
        { 
// ----- RemoveFromClientPool is basically RemoveClientGrid(c) seen above. 
         ClientHandle.RemoveFromClientPool(c, "Server Requested"); 
        } 
        else 
         if (debugWindow != null) 
          debugWindow.LogTextBox.AppendText("Unable to find client!"); 
       } 
      } 
     } 
    } 

} 

1) ... GUI를의 사진입니다 . 행 번호는 RowContainer 클래스에 지정되어 있습니다.

2) 거의 동일한 우려 사항 ... 정확히 무슨 일이 발생했는지 모르겠다. 방금 행 번호를 삽입했다. 5 클라이언트가 있고 3 대째 wpf 그리드에 연결이 끊어진 경우 연결되는 다음 클라이언트가 3 번 행을 가져옵니다? 어리석게 들리니, 4시에 3시와 5시에 4시 될 것입니다.

3) 그리드에 대한 새로운 행을 생성하는 방법입니다. 그것은 못생긴지만 내 유일한 관심사가 작동하는 것 같습니다 정말 행 번호 0 내 기본 텍스트를 찍은 번호입니다. 그래서 카운트가 맞을 것 같은 새로운 줄에서 나를 시작할 것입니다. 이후 첫 번째 클라이언트는 해당 카운트 = 1 (단지 내가 전에 가지고있는 기본 행을 계산).

4) 글쎄, 이것이 내 주요 문제라고 생각한다. 모든 컨트롤과 행 자체를 제거합니다. 그것은 순간에 System.InvalidOperationException을 던지는 것처럼 보입니다. 하지만 내 행 번호 매기기가 꺼져 있다고 확신합니다.

---- 전체적인 문제 : a) 행이 남을 때 행 번호는 어떻게됩니까? (새 클라이언트가 오면 마지막 지점이 생기고 거기에 있던 다른 모든 클라이언트가 한 줄 위로 이동합니까?) b) wpf의 Grid에서 행 내의 모든 컨트롤을 포함하여 효율적으로 행을 제거하려면 어떻게해야합니까?

내 RowContainer 클래스에 문제가 있다고 생각하지 않습니다. 모든 작업을 수행 할 수 있기 때문에 atm이 더러운 것입니다. 그러나 그것은 분명히 어떤 실제적인 실수를 던지지 않을 것입니다.

public class RowContainer 
{ 

    public byte[] Image { get; set; } 
    public String state; 
    public String ip; 
    public String Os {get; set;} 
    public String bitacc; 
    public String idle {get; set;} 
    public Client client; 
    public int rowNumber { get; set; } 

    public RowContainer(Client c) 
    { 
     this.ip = c.getClientIp(); 
     this.client = c; 
    } 

    public void SetIdleTime(String time) 
    { 
     this.idle = time; 
    } 

    public void SetState(String st) 
    { 
     this.state = st; 
    } 

    public void SetBCAccount(String bc){ 
     this.bitacc = bc; 
    } 

    public String GetIp() 
    { 
     return this.ip; 
    } 

    public String GetBitAccount() 
    { 
     return this.bitacc; 
    } 

    public Client GetClient() 
    { 
     return this.client; 
    } 

    public String GetIdleTime() 
    { 
     return this.idle; 
    } 

    public String GetState() 
    { 
     return this.GetState(); 
    } 
} 

답변

1

여러분은 WPF에 익숙하지 않으므로 내 첫 번째 조언은 시간을 많이 보내고 MVVM에 대해 읽는 것입니다. 이것은 WPF의 주요 이점 중 하나입니다. 당신은 예를 들어 귀하의 질문에 대한 MVVM: Tutorial from start to finish?

에 대한 질문을 볼 수 있습니다, 그리드 컨트롤은 당신이 ItemsControl에를 사용하는 것이 좋을 것이다 항목의 목록을 표시 할 때 레이아웃 제어 (여기 좀 http://www.wpftutorial.net/GridLayout.html

를 취할 것입니다 예를 들어 ListBox). 여기에서 읽으십시오 : http://www.wpf-tutorial.com/list-controls/itemscontrol/ 이것은 유효한 색인을 유지하고 행의 생성 및 삭제를 처리하는 번거 로움을 덜어줍니다.