删除行&同一行中的所有控件

时间:2015-01-22 05:06:38

标签: c# wpf code-behind

下面我将附上我的窗口所有类(这是wpf)。我将评论我认为是问题/关注/问题的内容,之后我将按照清单顺序解释我的评论。最有帮助的答案将是那些使用代码作为参考回答所列问题的人。我将提供主窗口cs以及RowContainer类(简单管理类)。

以下是gui ... 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)我将此方法标记为RemoveFromRowList只是因为我不确定当我尝试删除行时是否所有行都需要向上移动。行号在RowContainer类中给出并保存。

2)几乎和一个问题一样......我不确定究竟发生了什么,所以我只是插入了一个行号...所以说如果有5个客户端并且第三个在wpf网格上断开连接那么下一个连接的客户端获取第3行?这听起来很傻请告诉我他们刚刚转移,因为4将是3和5将成为4 ...?

3)这是它为网格生成新行的方式。这很丑陋,但似乎工作我唯一关心的是我的第0行采用了我的默认文本。因此,我认为伯爵会在正确的新行开始。因为如果第一个客户端的计数= 1(仅计算我以前的默认行)。

4)我相信这是我的主要问题。删除所有控件和行本身。它似乎正在抛出System.InvalidOperationException。但我也确定我的行编号已关闭......

----总体问题:a)当行离开时行号会发生什么? (新客户端来了,它获得了最后一个位置,那里的所有其他客户端都被连续移动了?) b)如何在wpf中有效删除Grid中的行,包括该行中的所有控件?

我不相信我的RowContainer课程存在问题,因为我可以做到这一切,所以我只能这样做。但它显然不会抛出任何真正的错误。

 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 个答案:

答案 0 :(得分:0)

我想你是WPF的新手,所以我的第一个建议就是腾出一些时间来阅读MVVM。这是WPF的主要优势之一。你可以看一下这个问题 MVVM: Tutorial from start to finish?

关于你的问题,网格控件是一个布局控件,请看这里http://www.wpftutorial.net/GridLayout.html

如果要显示项目列表,最好使用ItemsControl(例如ListBox)。 在这里阅读:http://www.wpf-tutorial.com/list-controls/itemscontrol/这将为您节省维护有效索引和处理行的创建和删除的麻烦。