<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
请注意,设计器现在显示标签占据的可用高度较少。 现在,下一行有更多空间可用。 大多数控件会定义应该占用的最适合自己的某种高度和宽度值。 例如,标签控件有一个高度值,确保你可以读取它。
让我们谈谈控件的放置。 上一部分中创建的标签已自动放置在网格的第 0 行和第 0 列。 行和列的编号从 0 开始,每新增一行或一列,编号就递增 1。 控件无法识别网格,并且不会定义任何属性来控制其在网格中的位置。 控件甚至可能放置在其他布局控件中,后者有自己的一组规则来定义如何放置控件。
当控件无法识别网格时,如何告诉控件使用其他行或列? 附加属性! 网格采用 WPF 提供的强大属性系统。 网格定义了子控件可以声明和使用的新属性。 控件本身其实并不存在这些属性,它们是在将控件添加到网格时由网格附加的。
网格定义两个属性来确定子控件的行和列位置:Grid.Row
和 Grid.Column
。 如果控件中省略了这些属性,则意味着它们的默认值为 0,因此,控件将放置在网格的第 0
行和第 0
列。 尝试通过将 Grid.Column
属性设置为 1
来更改 <Label>
控件的位置:
<Label Grid.Column="1">Names</Label>
注意标签现在如何移动到第二列。 你可以使用 Grid.Row
和 Grid.Column
附加属性来放置我们接下来要创建的控件。 不过现在,请将标签还原到第 0 列。
创建名称列表框
现在已经正确调整了网格的大小并创建了标签,接下来,在标签下方的行中添加一个列表框控件。 列表框将位于第 1
行和第 0
列。 我们还将此控件命名为 lstNames
。 为控件命名后,即可在代码隐藏中对其进行引用。 该名称通过 x:Name
特性分配给控件。
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label>Names</Label>
<ListBox Grid.Row="1" x:Name="lstNames" />
</Grid>
添加其余控件
我们将添加的最后两个控件是一个文本框和一个按钮,用户将使用它们来输入要添加到列表框中的名称。 但是,我们没有尝试为网格创建更多行和列,而是将这些控件放入 <StackPanel>
布局控件中。
堆叠面板与网格的不同之处在于控件的放置方式。 你告诉网格你希望使用 Grid.Row
和 Grid.Column
附加属性将控件放置在哪个位置,堆叠面板则自动按以下方式运行:先放置第一个控件,然后将下一个控件置于其后,一直到所有控件都放置完毕。 它将每个控件“堆叠”在另一个控件之下。
在列表框后创建 <StackPanel>
控件,并将其放在网格的第 1
行、第 1
列。 另外添加一个名为 Margin
且值为 5,0,0,0
的特性:
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label>Names</Label>
<ListBox Grid.Row="1" x:Name="lstNames" />
<StackPanel Grid.Row="1" Grid.Column="1" Margin="5,0,0,0">
</StackPanel>
之前在网格上使用了 Margin
特性,但我们只输入了一个值 (10
)。 现在,我们在堆叠面板上使用了值 5,0,0,0
。 边距是 Thickness
类型,可以解释这两个值。 粗细定义矩形框每条边(分别为左、顶、右、底)周围的空间。 如果边距的值是单一值,则四条边均使用该值。
接下来,在 <StackPanel>
中创建 <TextBox>
和 <Button>
控件。
<StackPanel Grid.Row="1" Grid.Column="1" Margin="5,0,0,0">
<TextBox x:Name="txtName" />
<Button x:Name="btnAdd" Margin="0,5,0,0">Add Name</Button>
</StackPanel>
窗口的布局已完成。 但是,我们的应用不包含任何逻辑,无法真正发挥作用。 接下来,我们需要将控件事件挂钩到代码,让应用能够实际派上用场。
为 Click 事件添加代码
我们创建的 <Button>
具有一个 Click
事件,该事件在用户按下按钮时引发。 你可以订阅此事件并添加代码,以便向列表框添加名称。 就像通过添加 XAML 特性在控件上设置属性一样,你可以使用 XAML 特性来订阅事件。 将 Click
特性设置为 ButtonAddName_Click
<StackPanel Grid.Row="1" Grid.Column="1" Margin="5,0,0,0">
<TextBox x:Name="txtName" />
<Button x:Name="btnAdd" Margin="0,5,0,0" Click="ButtonAddName_Click">Add Name</Button>
</StackPanel>
现在,你需要生成处理程序代码。 右键单击 ButtonAddName_Click
,然后选择“转到定义”。 此操作将在代码隐藏中为你生成一个与你输入的处理程序名称匹配的方法。
private void ButtonAddName_Click(object sender, RoutedEventArgs e)
Private Sub ButtonAddName_Click(sender As Object, e As RoutedEventArgs)
End Sub
接下来,添加以下代码以执行这三个步骤:
确保文本框包含名称。
验证文本框中输入的名称是否已经存在。
将名称添加到列表框。
private void ButtonAddName_Click(object sender, RoutedEventArgs e)
if (!string.IsNullOrWhiteSpace(txtName.Text) && !lstNames.Items.Contains(txtName.Text))
lstNames.Items.Add(txtName.Text);
txtName.Clear();
Private Sub ButtonAddName_Click(sender As Object, e As RoutedEventArgs)
If Not String.IsNullOrWhiteSpace(txtName.Text) And Not lstNames.Items.Contains(txtName.Text) Then
lstNames.Items.Add(txtName.Text)
txtName.Clear()
End If
End Sub
现在已对事件进行编码,可以通过按 F5 键或从菜单中选择“调试”>“开始调试”来运行应用。 随即显示窗口,可以在文本框中输入名称,然后通过单击按钮添加该名称。
详细了解 Windows Presentation Foundation
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:https://aka.ms/ContentUserFeedback。
提交和查看相关反馈