如何在WPF中创建2x2网格,在元素更改可见性时调整大小

时间:2017-03-24 12:50:18

标签: wpf xaml

我试图在WPF中创建一个包含两列和两行的网格。我希望网格以一种特殊的方式调整大小,具体取决于哪些单元格可见,我已经做了一些插图来更好地解释:

案例1:一个项目可见 - 一个单元格填充所有可用空间

enter image description here

案例2;有两个项目可见 - 空间在行之间划分

enter image description here

案例3:可见三个项目 - 第2行分为两列

enter image description here

案例4:所有四个项目都可见 - 空间均匀分布

enter image description here

这篇文章:Resizing WPF Grid Column when other Columns children is collapsed?

描述如何使用可见性大小转换器解决单行的问题,但为了使其适用于两行,我必须将一行的大小绑定到两个元素的可见性。使用多重绑定可能是可能的,但我不确定这是否是最好的方法。也许有更好的方法来做这个而不是使用网格?

1 个答案:

答案 0 :(得分:1)

有点儿有趣的问题。基本上你想要在类中封装可移动项的概念,这样你就可以轻松地将Grid props绑定到可编程的东西上。在我的想法中,我为此创建了一个类型Cell。现在,当您希望布局移动时,您可以将所有道具绑定到一个对象。您将在视图模型中看到4种方法:ShowAllCellsShow3Cells等,这些都是您根据表示逻辑调用的。认为这就是它。

<强> XAML

<Window x:Class="WpfApplication7.MainWindow"
    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"
    xmlns:local="clr-namespace:WpfApplication7"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525"
    d:DataContext="{d:DesignInstance {x:Type local:MainWindowViewModel}}">
<Window.Resources>
    <Style TargetType="Rectangle">
        <Setter Property="Width" Value="50"/>
        <Setter Property="Height" Value="50"/>
        <Setter Property="HorizontalAlignment" Value="Center"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
    </Style>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Rectangle Fill="Red" Grid.Row="{Binding Cell1.Row}" Grid.Column="{Binding Cell1.Col}" Grid.ColumnSpan="{Binding Cell1.ColSpan}" Grid.RowSpan="{Binding Cell1.RowSpan}" Visibility="{Binding Cell1.Vis}" />
    <Rectangle Fill="Blue" Grid.Row="{Binding Cell2.Row}" Grid.Column="{Binding Cell2.Col}" Grid.ColumnSpan="{Binding Cell2.ColSpan}" Grid.RowSpan="{Binding Cell2.RowSpan}" Visibility="{Binding Cell2.Vis}" />
    <Rectangle Fill="Yellow" Grid.Row="{Binding Cell3.Row}" Grid.Column="{Binding Cell3.Col}" Grid.ColumnSpan="{Binding Cell3.ColSpan}" Grid.RowSpan="{Binding Cell3.RowSpan}" Visibility="{Binding Cell3.Vis}" />
    <Rectangle Fill="Green" Grid.Row="{Binding Cell4.Row}" Grid.Column="{Binding Cell4.Col}" Grid.ColumnSpan="{Binding Cell4.ColSpan}" Grid.RowSpan="{Binding Cell4.RowSpan}" Visibility="{Binding Cell4.Vis}" />
</Grid>

View-Model&amp;细胞

using System.ComponentModel;
using System.Windows;

namespace WpfApplication7
{
    public class Cell : INotifyPropertyChanged
    {
        private int row;

        public int Row
        {
            get { return row; }
            set
            {
                if (row == value) return;
                row = value;
                OnPropertyChanged(@"Row");
            }
        }

        private int col;

        public int Col
        {
            get { return col; }
            set
            {
                if (col == value) return;
                col = value;
                OnPropertyChanged(@"Col");
            }
        }

        private int rowSpan;

        public int RowSpan
        {
            get { return rowSpan; }
            set
            {
                if (rowSpan == value) return;
                rowSpan = value;
                OnPropertyChanged(@"RowSpan");
            }
        }

        private int colSpan;

        public int ColSpan
        {
            get { return colSpan; }
            set
            {
                if (colSpan == value) return;
                colSpan = value;
                OnPropertyChanged(@"ColSpan");
            }
        }

        private Visibility vis;

        public Visibility Vis
        {
            get { return vis; }
            set
            {
                if (vis == value) return;
                vis = value;
                OnPropertyChanged(@"Vis");
            }
        }

        #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler == null) return;
            var e = new PropertyChangedEventArgs(propertyName);
            handler(this, e);
        }

        #endregion
    }

    public class MainWindowViewModel 
    {
        public MainWindowViewModel()
        {
            Cell1 = new Cell();
            Cell2 = new Cell();
            Cell3 = new Cell();
            Cell4 = new Cell();

            // Call the one you want. 
            ShowAllCells();
            Show3Cells(Cell2, Cell3, Cell4, Cell1);
            Show2Cells(Cell2, Cell3, Cell4, Cell1);
            Show1Cell(Cell2, Cell3, Cell4, Cell1);
        }

        private void ShowAllCells()
        {
            Cell1.Row = 0;
            Cell1.Col = 0;
            Cell1.RowSpan = 1;
            Cell1.ColSpan = 1;
            Cell1.Vis = Visibility.Visible;
            Cell2.Row = 0;
            Cell2.Col = 1;
            Cell2.RowSpan = 1;
            Cell2.ColSpan = 1;
            Cell2.Vis = Visibility.Visible;
            Cell3.Row = 1;
            Cell3.Col = 0;
            Cell3.RowSpan = 1;
            Cell3.ColSpan = 1;
            Cell3.Vis = Visibility.Visible;
            Cell4.Row = 1;
            Cell4.Col = 1;
            Cell4.RowSpan = 1;
            Cell4.ColSpan = 1;
            Cell4.Vis = Visibility.Visible;
        }

        private void Show3Cells(Cell one, Cell two, Cell three, Cell hidden1)
        {
            one.Row = 0;
            one.Col = 0;
            one.RowSpan = 1;
            one.ColSpan = 2;
            one.Vis = Visibility.Visible;
            two.Row = 1;
            two.Col = 0;
            two.RowSpan = 1;
            two.ColSpan = 1;
            two.Vis = Visibility.Visible;
            three.Row = 1;
            three.Col = 1;
            three.RowSpan = 1;
            three.ColSpan = 1;
            three.Vis = Visibility.Visible;

            hidden1.Row = 0;
            hidden1.Col = 0;
            hidden1.RowSpan = 1;
            hidden1.ColSpan = 1;
            hidden1.Vis = Visibility.Collapsed;
        }

        private void Show2Cells(Cell one, Cell two, Cell hidden1, Cell hidden2)
        {
            one.Row = 0;
            one.Col = 0;
            one.RowSpan = 1;
            one.ColSpan = 2;
            one.Vis = Visibility.Visible;
            two.Row = 1;
            two.Col = 0;
            two.RowSpan = 1;
            two.ColSpan = 2;
            two.Vis = Visibility.Visible;

            hidden1.Row = 0;
            hidden1.Col = 0;
            hidden1.RowSpan = 1;
            hidden1.ColSpan = 1;
            hidden1.Vis = Visibility.Collapsed;
            hidden2.Row = 0;
            hidden2.Col = 0;
            hidden2.RowSpan = 1;
            hidden2.ColSpan = 1;
            hidden2.Vis = Visibility.Collapsed;
        }

        private void Show1Cell(Cell one, Cell hidden1, Cell hidden2, Cell hidden3)
        {
            one.Row = 0;
            one.Col = 0;
            one.RowSpan = 2;
            one.ColSpan = 2;
            one.Vis = Visibility.Visible;

            hidden1.Row = 0;
            hidden1.Col = 0;
            hidden1.RowSpan = 1;
            hidden1.ColSpan = 1;
            hidden1.Vis = Visibility.Collapsed;
            hidden2.Row = 0;
            hidden2.Col = 0;
            hidden2.RowSpan = 1;
            hidden2.ColSpan = 1;
            hidden2.Vis = Visibility.Collapsed;
            hidden3.Row = 0;
            hidden3.Col = 0;
            hidden3.RowSpan = 1;
            hidden3.ColSpan = 1;
            hidden3.Vis = Visibility.Collapsed;
        }

        public Cell Cell1 { get; set; }
        public Cell Cell2 { get; set; }
        public Cell Cell3 { get; set; }
        public Cell Cell4 { get; set; }
   }
}