[英]Adding Grid and Controls dynamically in WPF
I am now doing an application that shows the HDD usage in the system. 我现在正在做一个显示系统中HDD使用情况的应用程序。 For that I want to generate the grid and the controls (like progress bar and labels) dynamically to show the usage.
为此,我想动态生成网格和控件(如进度条和标签)以显示用法。 Is there any XAML template available for this purpose?
是否有可用于此目的的XAML模板?
I use the folowing code to generate controls dynamically in my code 我使用下面的代码在我的代码中动态生成控件
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) {}
}
The functions GetHardDiskDrives() and SetWindowHeight() are user defined functions. 函数GetHardDiskDrives()和SetWindowHeight()是用户定义的函数。 The jpb is to get harddrives and Set the window height according to the new controls added.
jpb用于获取硬盘并根据添加的新控件设置窗口高度。
I found the other answer confusing because of the inline-comments... adding a columnDEFINITION (for example) "draws" absolutely NOTHING - that's very misleading for beginners. 我发现另一个答案令人困惑,因为内联注释...添加一个columnDEFINITION(例如)“draw”绝对没有 - 这对初学者来说是非常误导的。
Also : the rows are selected repeatedly even though they have already been selected ... that just adds useless overhead. 另外:即使已经选择了行,也会重复选择行...这只会增加无用的开销。 This will make your app really really slow if you're using several hundred rows.
如果您使用数百行,这将使您的应用程序真的很慢。
Same with setting the WindowHeight. 与设置WindowHeight相同。
Here's a (somewhat) more efficient solution for dynamic row&column-management in VB.NET: (use Dispatcher.BeginInvoke() instead of Invoke() if you want to switch to asynchronous processing) 这是一个(某种程度上)更有效的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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.