簡體   English   中英

如何根據WPF中的窗口大小動態更改網格行和列

[英]How to dynamically change grid rows and columns according to window size in WPF

我正在制作各種圖像庫,當前正在通過C#將圖像動態加載到網格中。 如果我不應該使用網格來顯示圖像,我很樂意將其更改為更適合的控件,但是它需要對窗口大小進行調整。

調整窗口大小時,我希望發生以下事情:

  • 圖像均保持完全相同的尺寸。 它們已經適合網格插槽,同時保持了寬高比
  • 網格空間本身也根本不調整大小
  • 網格包含或多或少的行/列,具體取決於窗口中可以容納多少行/列

這意味着,如果將窗口的大小調整為非常薄且非常高,則網格將包含一列(或兩列,或者需要許多列)和許多行來顯示圖像。

如果它很寬但不高,那么它將只有一個(或兩個,或者需要許多)行和許多列。 等等。

不知道是否需要,但是我顯示圖像的代碼是:

        for (int i = 0; i < ImageGrid.RowDefinitions.Count; i++)
        {
            for (int j = 0; j < ImageGrid.ColumnDefinitions.Count; j++)
            {
                Image img = new Image();
                BitmapImage bitmap = new BitmapImage();

                using (var fs = new FileStream(path, FileMode.Open)) // open the image
                {
                    bitmap.BeginInit();
                    bitmap.StreamSource = fs;
                    bitmap.CacheOption = BitmapCacheOption.OnLoad;
                    bitmap.EndInit();
                }

                bitmap.Freeze(); // bitmap isn't properly cleaned up and memory leaks can occur if this isn't here

                img.Source = bitmap;

                img.Margin = new Thickness(10);

                img.Stretch = Stretch.Uniform;

                Grid.SetRow(img, i);
                Grid.SetColumn(img, j);

                ImageGrid.Children.Add(img);
            }
        }

我的表格的XAML是:

    <Grid ShowGridLines="True" Background="DimGray">
        <Grid.ColumnDefinitions>
            <ColumnDefinition MinWidth="175" Width="0"/>
            <ColumnDefinition MinWidth="755" Width="Auto"/>
        </Grid.ColumnDefinitions>

        <Label Name="lblWinSize" Content="Width, Height" 
HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
        <TextBox Name="txtnbox" Style="{StaticResource CustomTxtBox}" 
TextWrapping="NoWrap" Width="Auto" Height="25" VerticalAlignment="Top" 
Margin="10, 20, 10, 0"/>

        <Separator Style="{StaticResource VerticalSeparator}" 
HorizontalAlignment="Right" Height="Auto" Width="2" Margin="0,10,0,10"/>
        <CheckBox Style="{StaticResource CustomCheckBox}" 
HorizontalAlignment="Left" Margin="10,50,0,0" VerticalAlignment="Top"/>
        <Grid Name="ImageGrid" Grid.Column="1" Margin="10,10,0,10" 
ShowGridLines="True" Background="Gray">
            <!--this is the grid where the images would go-->
        </Grid>
    </Grid>

抱歉,該XAML的縮進格式無法正確設置。

行/列在代碼的其他地方定義,但是我認為不需要替換,因為我將其替換。

同樣,如果某些其他控件更適合,則可以更改為該控件。

您將要使用包裝面板。

<WrapPanel Orientation="Horizontal">
    <Image Width="50" Height="50" Source="bla.png" />
    <Image Width="50" Height="50" Source="bla.png" />
    <Image Width="50" Height="50" Source="bla.png" />
    <Image Width="50" Height="50" Source="bla.png" />
</WrapPanel>

使用WrapPanelScrollViewer內部添加新行之前,使用WrapPanel使項目的布局填充窗口的寬度,以允許垂直ScrollViewer以使內容不會超出可見區域。

<ScrollViewer>
  <WrapPanel HorizontalAlignment="Center">
    <!-- your items go here -->
  </WrapPanel>
</ScrollViewer>

如果圖像是動態添加的,則希望將它們添加到視圖可以綁定到的集合中,而不是直接在后面的代碼中將它們直接添加到視圖中...使用ItemsControl並為項目和容器定義自己的模板:

<ScrollViewer>
  <ItemsControl ItemsSource="{Binding Images}" HorizontalAlignment="Center">
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <Image Source="{Binding ...}" Height="150" Width="150"/>
      </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
        <WrapPanel />
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
  </ItemsControl>
</ScrollViewer>

C# :

// here set number of images you want to parse
        int qtyOfImages = 10;

        for (int i = 0; i < qtyOfImages; i++) {
            Image img = new Image();
            BitmapImage bitmap = new BitmapImage();

            using (var fs = new FileStream(path, FileMode.Open)) // open the image
            {
                bitmap.BeginInit();
                bitmap.StreamSource = fs;
                bitmap.CacheOption = BitmapCacheOption.OnLoad;
                bitmap.EndInit();
            }

            bitmap.Freeze(); // bitmap isn't properly cleaned up and memory leaks can occur if this isn't here

            img.Source = bitmap;

            img.Margin = new Thickness(10);

            img.Stretch = Stretch.Uniform;

            //Grid.SetRow(img, i);
            //Grid.SetColumn(img, j);

            // set width and height so the images stay at the same size
            img.Width = 300;
            img.Height = 300;

            ImageGrid.Children.Add(img);
        }

而您的xaml就像:

 <Grid ShowGridLines="True" Background="DimGray">
        <Grid.ColumnDefinitions>
            <ColumnDefinition MinWidth="175" Width="0"/>
            <ColumnDefinition MinWidth="755" Width="Auto"/>
        </Grid.ColumnDefinitions>

        <Label Name="lblWinSize" Content="Width, Height" 
        HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
        <TextBox Name="txtnbox"  Style="{StaticResource CustomTxtBox}"
            TextWrapping="NoWrap" Width="Auto" Height="25" VerticalAlignment="Top" 
            Margin="10, 20, 10, 0"/>

        <Separator Style="{StaticResource VerticalSeparator}" 
            HorizontalAlignment="Right" Height="Auto" Width="2" Margin="0,10,0,10"/>
        <CheckBox Style="{StaticResource CustomCheckBox}"
            HorizontalAlignment="Left" Margin="10,50,0,0" VerticalAlignment="Top"/>
        <!--<Grid Name="ImageGrid" Grid.Column="1" Margin="10,10,0,10" 
                    ShowGridLines="True" Background="Gray">
                --><!--this is the grid where the images would go--><!--
            </Grid>-->


        <!-- set size of wrap panel to your window acutal width -->
        <WrapPanel Orientation="Horizontal" Name="ImageGrid" Width="{Binding ElementName=Window, Path=ActualWidth}">

        </WrapPanel>

    </Grid>

不要忘記在Name="Window"放置Name="Window"以便此代碼起作用

希望能有所幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM