Подтвердить что ты не робот

Динамическое добавление сетки и элементов управления в WPF

Теперь я делаю приложение, которое показывает использование жесткого диска в системе. Для этого я хочу динамически генерировать сетку и элементы управления (например, индикатор выполнения и метки), чтобы показать использование. Есть ли какой-либо шаблон XAML для этой цели?

4b9b3361

Ответ 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 должен получить жесткие диски и установить высоту окна в соответствии с новыми добавленными элементами управления.

Ответ 2

Я нашел, что другой ответ запутывается из-за встроенных комментариев... добавление 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