自適應XAML佈局經驗總結 (二) 局部佈局設計模式1

本系列對實際項目中的XAML佈局場景進行總結,給出了較優化的自適應佈局解決方案,但願對你們有所幫助。html

下面開始介紹局部佈局設計模式。express

1. 工具欄模式

適用於工具欄,標題等的佈局。設計模式

此塊佈局區域外層使用Grid,而後分爲兩行或三行,標題或工具欄區域爲Auto,主要內容區域爲*。若是是標題,使用TextBlock,設置文字的字體和字號,還有Margin,把此行撐開。若是是工具欄,可放置一個橫向的StackPanel,右對齊,其中放置多個按鈕,經過設置按鈕的Content,Margin和Padding,把此行撐開。Content能夠是文字,也能夠是圖標或圖標加文字。工具

image

<Window x:Class="BlendDemo.DP1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="工具欄模式" Height="300" Width="400">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Border Background="LightCyan">
            <TextBlock Margin="5" Text="此處爲標題" TextTrimming="WordEllipsis"/>
        </Border>
        <Grid Grid.Row="1" Background="AliceBlue"/>
    </Grid>
</Window>

標題和工具欄能夠在一行上,這時再放置一個Grid,把該行分爲兩列,標題在左邊,其列爲*,工具欄在右邊,其列爲Auto,標題和工具欄的處理方式和前述方式相似,若是工具欄較高,標題設置爲垂直居中對齊便可。佈局

image

<Window x:Class="BlendDemo.DP1a"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="工具欄模式" Height="300" Width="400">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid Background="LightCyan">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock Margin="5" VerticalAlignment="Center" Text="此處爲標題" TextTrimming="WordEllipsis"/>
            <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
                <Button Margin="0,5,5,5" Padding="15,5" Content=""/>
                <Button Margin="0,5,5,5" Padding="15,5" Content=""/>
                <Button Margin="0,5,5,5" Padding="15,5" Content=""/>
            </StackPanel>
        </Grid>
        <Grid Grid.Row="1" Background="AliceBlue"/>
        <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right">
            <Button Margin="0,5,5,5" Padding="15,5" Content="按鈕1"/>
            <Button Margin="0,5,5,5" Padding="15,5" Content="按鈕2"/>
            <Button Margin="0,5,5,5" Padding="15,5" Content="按鈕3"/>
        </StackPanel>
    </Grid>
</Window>

更復雜的狀況,標題可能由多個部分組成,這時標題部分再由Grid分爲多個列,前幾個列爲Auto,最後一個爲*,最後一個部分設置文字截斷。工具欄部分若是要實現按鈕大小相等的效果,能夠使用Grid替代StackPanel,Grid設置多列爲Auto,並設置 Grid.IsSharedSizeScope ="True",設置列寬時把SharedSizeGroup 設置爲相同的字符串便可。這時再設置按鈕的Content,Margin和Padding,按鈕的大小都爲由最大內容撐開的大小。字體

image

<Window x:Class="BlendDemo.DP1b"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="工具欄模式" Height="300" Width="400">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid Background="LightCyan">
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Grid VerticalAlignment="Center">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <TextBlock Margin="5,5,0,5" Text="標題第1部分"/>
                <TextBlock Grid.Column="1" Margin="5,5,0,5" Text="-"/>
                <TextBlock Grid.Column="2" Margin="5,5,0,5" Text="標題第2部分" TextTrimming="WordEllipsis"/>
            </Grid>
            <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
                <Button Margin="0,5,5,5" Padding="15,5" Content=""/>
                <Button Margin="0,5,5,5" Padding="15,5" Content=""/>
                <Button Margin="0,5,5,5" Padding="15,5" Content=""/>
            </StackPanel>
        </Grid>
        <Grid Grid.Row="1" Background="AliceBlue"/>
        <Grid Grid.Row="2" HorizontalAlignment="Right" Grid.IsSharedSizeScope="True">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" SharedSizeGroup="c1"/>
                <ColumnDefinition Width="Auto" SharedSizeGroup="c1"/>
                <ColumnDefinition Width="Auto" SharedSizeGroup="c1"/>
            </Grid.ColumnDefinitions>
            <Button Margin="0,5,5,5" Padding="15,5" Content="按鈕按鈕1"/>
            <Button Grid.Column="1" Margin="0,5,5,5" Padding="10,5" Content="按鈕2"/>
            <Button Grid.Column="2" Margin="0,5,5,5" Padding="10,5" Content="按鈕3"/>
        </Grid>
    </Grid>
</Window>

 

2. 壓縮空白模式

一塊顯示區域較大,但顯示內容較少,這時能夠把這塊區域使用Grid佈局,顯示的區域使用Auto,剩餘的空白區域使用多個不一樣比例的*分割。好比左側的查詢欄,兩塊查詢條件區和按鈕區是有效顯示區,這三塊區域使用Auto,四塊空白區域使用4*,4*, 4*, 3*分割,可以達到較好的效果。按鈕區域又使用了這個模式,分爲5列,按鈕部分爲Auto,空白部分爲2*,*, 2* ,中間的*還設置了最小寬15,這樣在必定範圍內能作到較好的自適應效果。優化

image

<Window x:Class="BlendDemo.DP2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="壓縮空白模式" Height="400" Width="600">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" MinWidth="165"/>
            <ColumnDefinition Width="3*"/>
        </Grid.ColumnDefinitions>
        <Border Background="LightCyan">
            <Grid Margin="10,0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="4*"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="4*"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="4*"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="3*"/>
                </Grid.RowDefinitions>
                <StackPanel Grid.Row="1">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Margin="5" VerticalAlignment="Center" Text="姓名:"/>
                        <TextBox Grid.Column="1" Margin="0,5,5,5" Padding="2"/>
                    </Grid>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Margin="5" VerticalAlignment="Center" Text="性別:"/>
                        <ComboBox Grid.Column="1" Margin="0,5,5,5" Padding="2"/>
                    </Grid>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Margin="5" VerticalAlignment="Center" Text="年齡:"/>
                        <TextBox Grid.Column="1" Margin="0,5,5,5" Padding="2"/>
                    </Grid>
                </StackPanel>
                <StackPanel Grid.Row="3">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Margin="5" VerticalAlignment="Center" Text="起始:"/>
                        <DatePicker Grid.Column="1" Margin="0,5,5,5" Padding="2"/>
                    </Grid>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Margin="5" VerticalAlignment="Center" Text="截至:"/>
                        <DatePicker Grid.Column="1" Margin="0,5,5,5" Padding="2"/>
                    </Grid>
                </StackPanel>
                <Grid Grid.Row="5">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="2*"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="*" MinWidth="15"/>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="2*"/>
                    </Grid.ColumnDefinitions>
                    <Button Grid.Column="1" Content="查詢" Padding="15,5"/>
                    <Button Grid.Column="3" Content="清空" Padding="15,5"/>
                </Grid>
            </Grid>
        </Border>
        <Grid Grid.Column="1" Background="AliceBlue"/>
    </Grid>
</Window>

 

3. 表單模式

若是要完成一個表單,能夠使用Grid分爲多行多列,行爲Auto,列爲Auto和*相間,其中標籤部分爲Auto,填寫內容部分爲*。每一個部分都設置合適的字體字號,Margin和Padding,而不設置固定的大小,這樣就能完成一個自適應的表單。若是有的填寫內容長些,能夠設置跨列爲3,跨越兩個大的區域,或更大的數跨越更多的區域。spa

image

<Window x:Class="BlendDemo.DP3"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="表單模式" Height="400" Width="600">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid Background="LightCyan">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <TextBlock Margin="5" VerticalAlignment="Center" Text="姓名:"/>
            <TextBox Margin="0,5" Grid.Column="1" Padding="2"/>
            <TextBlock Grid.Column="2" Margin="5" VerticalAlignment="Center" Text="性別:" TextTrimming="WordEllipsis"/>
            <ComboBox Grid.Column="3" Margin="0,5" Padding="2"/>
            <TextBlock Grid.Column="4" Margin="5" VerticalAlignment="Center" Text="年齡:" TextTrimming="WordEllipsis"/>
            <TextBox Grid.Column="5" Margin="0,5,5,5" Padding="2"/>
            <TextBlock Grid.Row="1" Margin="5" VerticalAlignment="Center" Text="電話:"/>
            <TextBox Grid.Row="1" Margin="0,5" Grid.Column="1" Padding="2"/>
            <TextBlock Grid.Column="2" Grid.Row="1" Margin="5" VerticalAlignment="Center" Text="地址:" TextTrimming="WordEllipsis"/>
            <TextBox Grid.Column="3" Grid.ColumnSpan="3" Grid.Row="1" Margin="0,5,5,5" Padding="2"/>
        </Grid>
        <Grid Grid.Row="1" Background="AliceBlue"/>
    </Grid>
</Window>

 

4. 表格模式

能夠使用下述Grid佈局組合的方式顯示錶格數據,但更好的方式是使用DataGrid控件。設計

首先,在最外層放一個ScrollViewer,設置水平滾動條可見性爲Auto,垂直滾動條可見性爲Disabled。其中放置一個Border用於顯示錶格線。在其中放置一個Grid,分爲2行,第0行爲Auto,第1行爲*。3d

而後,在外層Grid中第0行的位置上放置一個Grid,分爲幾列,設置必定的寬度,每列中放置一個Border顯示錶格線,Border中放一個TextBlock,顯示列標題,設置水平居中對齊,和合適的Margin。除了最後一列,還放置了GridSplitter,用於調節列的寬度。

最後,在外層Grid中第1行的位置上放置一個ScrollViewer,設置垂直滾動條可見性爲Auto。其中放置一個ItemsControl,綁定到合適的數據,設置數據模板爲Grid,分爲和標題Grid一致的列數,使用SharedSizeGroup保證列的寬度和標題Grid的列的寬度一致。每列中放置一個Border顯示錶格線,Border中放一個TextBlock,Text綁定到數據中對應的屬性上,設置水平居中對齊,和合適的Margin。

image

<Window x:Class="BlendDemo.DP4"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="表格模式" Height="600" Width="800">
    <Grid>
        <ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
            <Border BorderBrush="Black" BorderThickness="0.5">
                <Grid Grid.IsSharedSizeScope="True">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="200" SharedSizeGroup="c1"/>
                            <ColumnDefinition Width="200" SharedSizeGroup="c2"/>
                            <ColumnDefinition Width="200" SharedSizeGroup="c3"/>
                            <ColumnDefinition Width="200" SharedSizeGroup="c4"/>
                            <ColumnDefinition Width="200" SharedSizeGroup="c5"/>
                        </Grid.ColumnDefinitions>
                        <Border Grid.Column="0" BorderBrush="Black" BorderThickness="0.3">
                            <TextBlock Text="第1列" HorizontalAlignment="Center" Margin="5"/>
                        </Border>
                        <GridSplitter Grid.Column="0" Width="2" HorizontalAlignment="Right"/>
                        <Border Grid.Column="1" BorderBrush="Black" BorderThickness="0.3">
                            <TextBlock Text="第2列" HorizontalAlignment="Center" Margin="5"/>
                        </Border>
                        <GridSplitter Grid.Column="1" Width="2" HorizontalAlignment="Right"/>
                        <Border Grid.Column="2" BorderBrush="Black" BorderThickness="0.3">
                            <TextBlock Text="第3列" HorizontalAlignment="Center" Margin="5"/>
                        </Border>
                        <GridSplitter Grid.Column="2" Width="2" HorizontalAlignment="Right"/>
                        <Border Grid.Column="3" BorderBrush="Black" BorderThickness="0.3">
                            <TextBlock Text="第4列" HorizontalAlignment="Center" Margin="5"/>
                        </Border>
                        <GridSplitter Grid.Column="3" Width="2" HorizontalAlignment="Right"/>
                        <Border Grid.Column="4" BorderBrush="Black" BorderThickness="0.3">
                            <TextBlock Text="第5列" HorizontalAlignment="Center" Margin="5"/>
                        </Border>
                    </Grid>
                    <ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
                        <ItemsControl ItemsSource="{Binding}">
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition SharedSizeGroup="c1"/>
                                            <ColumnDefinition SharedSizeGroup="c2"/>
                                            <ColumnDefinition SharedSizeGroup="c3"/>
                                            <ColumnDefinition SharedSizeGroup="c4"/>
                                            <ColumnDefinition SharedSizeGroup="c5"/>
                                        </Grid.ColumnDefinitions>
                                        <Border Grid.Column="0" BorderBrush="Black" BorderThickness="0.3">
                                            <TextBlock Text="{Binding Column1}" HorizontalAlignment="Center" Margin="5"/>
                                        </Border>
                                        <Border Grid.Column="1" BorderBrush="Black" BorderThickness="0.3">
                                            <TextBlock Text="{Binding Column2}" HorizontalAlignment="Center" Margin="5"/>
                                        </Border>
                                        <Border Grid.Column="2" BorderBrush="Black" BorderThickness="0.3">
                                            <TextBlock Text="{Binding Column3}" HorizontalAlignment="Center" Margin="5"/>
                                        </Border>
                                        <Border Grid.Column="3" BorderBrush="Black" BorderThickness="0.3">
                                            <TextBlock Text="{Binding Column4}" HorizontalAlignment="Center" Margin="5"/>
                                        </Border>
                                        <Border Grid.Column="4" BorderBrush="Black" BorderThickness="0.3">
                                            <TextBlock Text="{Binding Column5}" HorizontalAlignment="Center" Margin="5"/>
                                        </Border>
                                    </Grid>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </ScrollViewer>
                </Grid>
            </Border>
        </ScrollViewer>
    </Grid>
</Window>
    public class TableDataItem
    {
        public string Column1 { get; set; }
        public string Column2 { get; set; }
        public string Column3 { get; set; }
        public string Column4 { get; set; }
        public string Column5 { get; set; }
    }

    public partial class DP4 : Window
    {
        public DP4()
        {
            InitializeComponent();
            var data = new List<TableDataItem>();
            for (var i = 0; i < 30; i++)
            {
                data.Add(new TableDataItem { Column1 = "第1列數據", Column2 = "第2列數據", Column3 = "第3列數據", Column4 = "第4列數據", Column5 = "第5列數據" });
            }
            DataContext = data;
        }
    }
相關文章
相關標籤/搜索