【问题标题】:Adding Grid and Controls dynamically in WPF在 WPF 中动态添加网格和控件
【发布时间】:2017-07-27 14:32:45
【问题描述】:

我现在正在做一个显示系统中 HDD 使用情况的应用程序。为此,我想动态生成网格和控件(如进度条和标签)以显示使用情况。是否有任何 XAML 模板可用于此目的?

【问题讨论】:

    标签: wpf xaml templates wpf-controls


    【解决方案1】:

    我使用以下代码在我的代码中动态生成控件

    Label[] drivesLabel;
    Label[] percentageLabel;
    ProgressBar[] drivesProgress;
    int drivesCount = 0;
    
    private void DrawControls()
    {
        try
        {
            // Getting drive list.
            List<DriveInfo> driveList = GetHardDiskDrives();
            drivesCount = driveList.Count;
    
            // Initializing new Grid.
            Grid drivesGrid = new Grid();
            drivesGrid.Children.Clear();
            DrivesBorder.Child = drivesGrid;
    
            // Adding Rows and Colums to Grid.
            RowDefinition[] rows = new RowDefinition[2*drivesCount + 1];
            ColumnDefinition[] columns = new ColumnDefinition[6];
    
            // Draw Rows.
            for (int i = 0; i < 2*drivesCount + 1; i++)
            {
                rows[i] = new RowDefinition();
                drivesGrid.RowDefinitions.Add(rows[i]);
    
                // Setting Row height.
                rows[i].Height = (0 == i % 2) ? new GridLength( 5 ): new GridLength( 25 );
            }
            // Draw Columns.
            for (int i = 0; i < 6; i++)
            {
                columns[i] = new ColumnDefinition();
                drivesGrid.ColumnDefinitions.Add(columns[i]);
                if (i % 2 == 0)
                {
                    // Setting column width.
                    columns[i].Width = new GridLength(5);
                }
            }
    
            // Setting column width.
            columns[1].Width = new GridLength(60);
            columns[3].Width = new GridLength(180);
            columns[5].Width = new GridLength(60);
    
            // Draw Labels to show drive letters.
            drivesLabel = new Label[drivesCount];
    
            // Draw Progress bar to show drive usage.
            drivesProgress = new ProgressBar[drivesCount];
    
            // Draw Labels to show drive usage.
            percentageLabel = new Label[drivesCount];
    
            // Adding Labels and Progressbars to Grid.
            for (int i = 0, j = 1; i < drivesCount; i++, j++)
            {
                // Initialize Labels to show drives.
                drivesLabel[i] = new Label();
                drivesLabel[i].Content = driveList[i].Name;
                drivesLabel[i].Foreground = Brushes.Navy;
                Grid.SetRow(drivesLabel[i], i + j);
                Grid.SetColumn(drivesLabel[i], 1);
                drivesGrid.Children.Add(drivesLabel[i]);
    
                // Initialize ProgressBar to show usage.
                drivesProgress[i] = new ProgressBar();
                drivesProgress[i].FlowDirection = FlowDirection.LeftToRight;
                drivesProgress[i].HorizontalAlignment = HorizontalAlignment.Center;
                drivesProgress[i].VerticalAlignment = VerticalAlignment.Center;
                drivesProgress[i].Orientation= Orientation.Horizontal;
                drivesProgress[i].Value = 0;
                drivesProgress[i].Maximum = 100;
                drivesProgress[i].Width = 180;
                drivesProgress[i].Height = 18;
                Grid.SetRow(drivesProgress[i], i + j);
                Grid.SetColumn(drivesProgress[i], 3);
                drivesGrid.Children.Add(drivesProgress[i]);
    
                // Initialize Labels  to show usage in percentage.
                percentageLabel[i] = new Label();
                percentageLabel[i].Content = "0 %";
                Grid.SetRow(percentageLabel[i], i + j);
                Grid.SetColumn(percentageLabel[i], 5);
                drivesGrid.Children.Add(percentageLabel[i]);
    
                // Setting window height.
                SetWindowHeight(30);
            }
        }
        catch(Exception Ex) {}
    }
    

    函数 GetHardDiskDrives() 和 SetWindowHeight() 是用户定义的函数。 jpb是获取硬盘并根据新添加的控件设置窗口高度。

    【讨论】:

    • 一千感谢 Shining Annatar,这正是我要找的伙伴 :)
    【解决方案2】:

    由于 inline-cmets,我发现另一个答案令人困惑......添加一个 columnDEFINITION(例如)“绘制”绝对没有 - 这对初学者来说非常误导。

    另外:即使已经选择了行,也会重复选择这些行……这只会增加无用的开销。如果您使用数百行,这将使您的应用程序非常慢。

    与设置 WindowHeight 相同。

    这是 VB.NET 中动态行和列管理的(稍微)更有效的解决方案: (如果要切换到异步处理,请使用 Dispatcher.BeginInvoke() 而不是 Invoke())

    Private Delegate Sub MyDelegate3(ByVal iByte As Byte)
    Private Delegate Function MyDelegate4() As Byte
    
    Public Property GridColumns As Byte
            Get
                Dim del As New MyDelegate4(AddressOf GetColumns)
                Return grid.Dispatcher.Invoke(del)
            End Get
    
            Set(ByVal value As Byte)
                Dim del As MyDelegate3
                If GridColumns > 0 Then
                    Dim diff As SByte = GridColumns - value
                    If diff > 0 Then    'Spalten abziehen
                        del = New MyDelegate3(AddressOf RemColDefs)
                        grid.Dispatcher.Invoke(del, diff)
                    Else                'Spalten hinzufügen
                        del = New MyDelegate3(AddressOf AddColDefs)
                        grid.Dispatcher.Invoke(del, Math.Abs(diff))
                    End If
                Else
                    del = New MyDelegate3(AddressOf AddColDefs)
                    grid.Dispatcher.Invoke(del, value)
                End If
            End Set
        End Property
    
        Public Property GridRows As Byte
            Get
                Dim del As New MyDelegate4(AddressOf GetRows)
                Return grid.Dispatcher.Invoke(del)
            End Get
            Set(value As Byte)
                Dim del As MyDelegate3
                If GridRows > 0 Then
                    Dim diff As SByte = GridRows - value
                    If diff > 0 Then    'Zeilen abziehen
                        del = New MyDelegate3(AddressOf RemRowDefs)
                        grid.Dispatcher.Invoke(del, diff)
                    Else                'Spalten hinzufügen
                        del = New MyDelegate3(AddressOf AddRowDefs)
                        grid.Dispatcher.Invoke(del, Math.Abs(diff))
                    End If
                Else
                    del = New MyDelegate3(AddressOf AddRowDefs)
                    grid.Dispatcher.Invoke(del, value)
                End If
            End Set
        End Property
    
        Private Function GetRows() As Byte
            Return grid.RowDefinitions.Count
        End Function
        Private Function GetColumns() As Byte
            Return grid.ColumnDefinitions.Count
        End Function
    
        Private Sub AddRowDefs(ByVal iRows As Byte)
            For r As Byte = 1 To iRows
                Dim rowDef As New RowDefinition
                rowDef.Height = GridLength.Auto
                grid.RowDefinitions.Add(rowDef)
            Next         
        End Sub
        Private Sub RemRowDefs(ByVal iRows As Byte)
            For r As Byte = 1 To iRows
                If grid.RowDefinitions.Count > 0 Then
                    grid.RowDefinitions.Remove(grid.RowDefinitions(0))
                End If
            Next            
        End Sub
    
        Private Sub AddColDefs(ByVal iCols As Byte)
            For r As Byte = 1 To iCols
                Dim colDef As New ColumnDefinition
                colDef.Width = GridLength.Auto
                grid.ColumnDefinitions.Add(colDef)
            Next            
        End Sub
        Private Sub RemColDefs(ByVal iCols As Byte)
            For r As Byte = 1 To iCols
                If grid.ColumnDefinitions.Count > 0 Then
                    grid.ColumnDefinitions.Remove(grid.ColumnDefinitions(0))
                End If
            Next            
        End Sub
    

    【讨论】:

      猜你喜欢
      • 2013-10-25
      • 1970-01-01
      • 2016-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-21
      相关资源
      最近更新 更多