2009-08-10 3 views
16

이제 시스템의 HDD 사용량을 보여주는 응용 프로그램을 수행 중입니다. 이를 위해 그리드와 컨트롤 (진행률 막대 및 레이블과 같은)을 동적으로 생성하여 사용법을 보여주고 싶습니다. 이 목적으로 사용할 수있는 XAML 템플릿이 있습니까?WPF에서 동적으로 격자 및 컨트롤 추가

답변

16

나는

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() 사용자 정의 함수입니다 내 코드에서 동적으로 컨트롤을 생성하는 folowing 코드를 사용합니다. jpb는 하드 드라이브를 얻고 추가 ​​된 새 컨트롤에 따라 창 높이를 설정합니다.

+0

감사합니다 빛나는 Annatar, 이것은 정확히 내가 짝을 찾고 있었던 것입니다 :) –

1

인라인 주석 때문에 다른 대답이 혼란 스러웠습니다 ... columnDEFINITION을 추가하면 (예를 들어) "전혀"그릴 필요가 없습니다. 초보자에게는 오해의 소지가 있습니다.

또한 행이 이미 선택되었지만 반복적으로 선택됩니다 ... 쓸데없는 오버 헤드가 추가됩니다. 이렇게하면 수백 개의 행을 사용하는 경우 앱이 정말 느려집니다.

WindowHeight 설정과 동일합니다. 여기

은 VB.NET 동적 행 & 열 관리를위한 (약간) 더 효율적인 솔루션입니다 :

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 
(비동기 처리로 전환하려는 경우 Dispatcher.BeginInvoke() 대신 호출()를 사용)