首页 文章

如何根据WPF中的窗口大小动态更改网格行和列

提问于
浏览
1

我正在制作各种图像库,我正在通过C#动态地将图像加载到网格中 . 如果我不应该使用网格来显示图像,我非常愿意将其更改为更适合的控件,但它需要对窗口调整大小友好 .

当我调整窗口大小时,我希望发生以下事情:

  • 图像都保持完全相同的大小 . 它们已经适合网格插槽,同时保持其纵横比

  • 网格空间本身也没有调整大小

  • 网格 contains more or less rows/columns depending on how many can fit into the window .

这意味着,如果窗口被调整为非常薄且非常高,则网格将包含一列(或两列,或者需要多少)以及用于显示图像的许多行 .

如果它非常宽,但不高,那么它只有一个(或两个,或者需要很多)行和许多列 . 等等 .

不确定是否需要,但显示图像的代码是:

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的缩进,我无法正确格式化 .

行/列在代码的其他地方定义,但我认为我不需要粘贴它,因为它将被替换 .

同样,如果其他控件更适合,我可以改为 .

3 回答

  • 1

    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" 以使此代码正常工作

    希望有所帮助

  • 0

    您将需要使用包装面板 .

    <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>
    
  • 1

    ScrollViewer 内添加新行之前,使用 WrapPanel 使项目布局填充窗口宽度,以允许垂直滚动,以使内容不会超出可视区域 .

    <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>
    

相关问题