繁体   English   中英

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

[英]Removing Row & All Controls in Same Row

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

这是GUI的图片。 在此处输入图片说明

  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类有问题,因为我可以做所有的事情,这只是肮脏的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();
    }
}

我想您是WPF的新手,所以我的第一条建议是腾出一些时间来阅读MVVM。 这是WPF的主要优势之一。 您可以查看该问题,例如MVVM:从头到尾的教程?

关于您的问题,网格控件是一种布局控件,请在此处查看http://www.wpftutorial.net/GridLayout.html

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM