ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

一文搞懂WPF布局

2021-09-10 13:58:44  阅读:209  来源: 互联网

标签:控件 UniformGrid 选项卡 一文 布局 TabControl 按钮 搞懂 WPF


文章目录

TabControl

TabControl即选项卡,通过TabStripPlacement可以调整选项卡的标题的位置;其内部则由一个个不同的TabItem构成,每个TabItem通过Header来声明标题。

例如

<TabControl TabStripPlacement ="Left">
    <TabItem Header="布局学习" >
        
    </TabItem>
</TabControl>

在这里插入图片描述

在主界面的布局学习选项卡中添加

<TabControl>
  <TabItem Header="TabControl">
      <TabControl TabStripPlacement="Bottom">
          <TabItem Header="Bottom"/>
      </TabControl>
  </TabItem>

  <TabItem Header="Grid">
  </TabItem>

  <TabItem Header="Canvas">
  </TabItem>

  <TabItem Header="WrapPanel">
  </TabItem>

  <TabItem Header="DockPanel">
  </TabItem>

  <TabItem Header="StackPanel">
  </TabItem>

  <TabItem Header="TabPanel">
  </TabItem>
</TabControl>

在这里插入图片描述

UniformGird

顾名思义,Grid即网格,UniformGrid即处处相同的网格,只能定义行数和列数,而每行每列的尺寸是不能定义的。

例如在Uniform选项卡下添加一个两行两列的UniformGrid:

<UniformGrid Columns="2" Rows="2">
    <Button Background="red" Margin="10"/>
    <Button Background="green" Margin="10"/>
    <Button Background="blue" Margin="10"/>
    <Button Background="Yellow" Margin="10"/>
</UniformGrid>

在这里插入图片描述

Gird

相比之下,Grid则是一个比较高级的网格,可以自行定义行列的尺寸。但高级的同时也意味着繁琐,其内部的控件必须声明所在的行列。

在声明网格尺寸时,如果添加*,则表示按照比例。

<TabItem Header="Grid">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="150"/>
        <ColumnDefinition Width="250"/>
        <ColumnDefinition Width="400"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="2*"/>
        <RowDefinition Height="3*"/>
    </Grid.RowDefinitions>
    <Button Grid.Column="0" Grid.Row="0" Content="00" Margin="10"/>
    <Button Grid.Column="0" Grid.Row="1" Content="01" Margin="10"/>
    <Button Grid.Column="0" Grid.Row="2" Content="02" Margin="10"/>
    <Button Grid.Column="1" Grid.Row="0" Content="10" Margin="10"/>
    <Button Grid.Column="1" Grid.Row="1" Content="11" Margin="10"/>
    <Button Grid.Column="1" Grid.Row="2" Content="12" Margin="10"/>
    <Button Grid.Column="2" Grid.Row="0" Content="20" Margin="10"/>
    <Button Grid.Column="2" Grid.Row="1" Content="21" Margin="10"/>
    <Button Grid.Column="2" Grid.Row="2" Content="22" Margin="10"/>
</Grid>
</TabItem>

在这里插入图片描述

Canvas

传统的绝对布局,通过Left, Top, Bottom, Right来确定控件的位置。

<Canvas>
    <Button Canvas.Left="10" Canvas.Top="20" Content="L10,T20" />
    <Button Canvas.Left="100" Canvas.Bottom="200" Content="L100,B200" />
    <Button Canvas.Right="250" Canvas.Top="50" Content="R250,T50" />
    <Button Canvas.Left="450" Canvas.Top="30" Content="450,30" />
</Canvas>

在这里插入图片描述

WrapPanel

可以换行的顺序布局模式。

<WrapPanel>
    <Button Height="30" Width="100" Margin="10"/>
    <Button Height="30" Width="100" Margin="10"/>
    <Button Height="30" Width="100" Margin="10"/>
    <Button Height="30" Width="100" Margin="10"/>
    <Button Height="30" Width="100" Margin="10"/>
    <Button Height="30" Width="100" Margin="10"/>
    <Button Height="30" Width="100" Margin="10"/>
</WrapPanel>

在这里插入图片描述

DockPanel

DockPanel是十分灵活的布局模式,可以理解为按照指示填充剩余空间。

<DockPanel>
    <Button DockPanel.Dock="Left" Content="Left" Margin="10"/>
    <Button DockPanel.Dock="Top" Content="Top" Margin="10"/>
    <Button DockPanel.Dock="Right" Content="right" Margin="10"/>
    <Button DockPanel.Dock="Bottom" Content="Bottom" Margin="10"/>
    <Button Content="Last" Margin="10"/>
</DockPanel>

在这里插入图片描述

如图所示,我们首先填充的是一个靠左的内容为Left的按钮,则这个Left填充了全部的左面的内容;然后是一个靠上的内容为Top的按钮,这个按钮填充了剩余空间的上部分。

DockPanel控件默认LastChildFillTrue,即最后一个控件填充剩余的所有空间,所以最后的那个last按钮才会这么大。

stackPanel

可以理解为不能换行的WrapPanel或者分布不均匀的UniformGrid。通过Orientation可以调整方向。

<StackPanel Orientation="Vertical">
    <StackPanel Orientation="Horizontal">
        <Button Content="btn1" Width="200" Margin="10"/>
        <Button Content="btn2" Width="300" Margin="10"/>
        <Button Content="btn3" Width="400" Margin="10"/>
    </StackPanel>
    <Button Content="btn5" Margin="10"/>
    <Button Content="btn6" Margin="10"/>
</StackPanel>

在这里插入图片描述

布局相关

TabPanel

其实就是TabControl的标题栏,根据前面案例的一些经验,可以猜测默认的TabPanel有点类似于WrapPanel,毕竟可以回车。

那么有没有办法让其变成均匀的分布,就像UniformGrid一样?方法就是把TabPanel的风格换成UniformGrid。

<TabItem Header="tabPanel">
   <TabItem.Resources>
       <Style TargetType="{x:Type TabControl}">
           <Setter Property="Template">
               <Setter.Value>
                   <ControlTemplate TargetType="{x:Type TabControl}">
                       <Grid>
                           <Grid.RowDefinitions>
                               <RowDefinition Height="Auto"/>
                               <RowDefinition Height="*"/>
                           </Grid.RowDefinitions>
                           <UniformGrid x:Name="HeaderPanel" Rows="1" 
                                    IsItemsHost="True" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/>
                       </Grid>
                   </ControlTemplate>
               </Setter.Value>
           </Setter>
       </Style>
   </TabItem.Resources>
   <TabControl>
       <TabItem Header="tab1"/>
       <TabItem Header="tab2" />
       <TabItem Header="tab3" />
       <TabItem Header="tab4" />
       <TabItem Header="tab5" />
   </TabControl>
</TabItem>

通过修改模板,就能够达到如下效果

在这里插入图片描述

virtualizingPanel

顾名思义,即虚拟化模板,对窗口外部的信息进行虚化,从而提高布局过程中的性能。为了实现这一点,也必须同ScrollViewer共同使用。

<TabItem Header="VirtualizingPanel ">
   <ScrollViewer>
       <StackPanel>
           <Button Content="btnLoad" Width="60" Height="20" Click="btnLoad_Click"/>
           <ListBox MinWidth="600" VirtualizingStackPanel.IsVirtualizing="False"  x:Name="lbData"
              ItemsSource="{Binding XPath=Team}"/>
       </StackPanel>
   </ScrollViewer>
</TabItem>

为了测试其性能,我们在后台添加10000个按钮试一下。

private void btnLoad_Click(object sender, RoutedEventArgs e)
{
   for (int i = 0; i < 10000; ++i)
       lbData.Items.Add(new Button { Width=60,Height=20,Content=i.ToString()});
}

标签:控件,UniformGrid,选项卡,一文,布局,TabControl,按钮,搞懂,WPF
来源: https://blog.csdn.net/m0_37816922/article/details/120220472

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有