【问题标题】:How can i create a 2x2 grid in WPF that resizes when elements change visibility如何在 WPF 中创建一个 2x2 网格,当元素改变可见性时调整大小
【发布时间】:2017-03-24 12:50:18
【问题描述】:

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

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

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

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

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

此帖:Resizing WPF Grid Column when other Columns children is collapsed?

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

【问题讨论】:

  • 第1行有2列,第2行只有1列吗?
  • 我只需要上面显示的情况,所以没有必要。
  • 只是为了确定:在情况 1、2 或 3 中,您的四个项目中的哪一个不可见并不重要?
  • 不,没关系。
  • 想一想,它不必依赖可见性。如果这能以某种方式简化解决方案,我就不需要所有四个项目都在那里

标签: wpf xaml


【解决方案1】:

一个有趣的问题。基本上,您希望将可移动项目的概念封装在一个类中,以便您可以轻松地将 Grid 道具绑定到可编程的东西。在我的想法中,我为此创建了一个类型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>

视图模型和单元格

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

【讨论】:

  • 非常优雅的解决方案!谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-24
  • 2012-06-24
  • 1970-01-01
  • 2021-12-23
相关资源
最近更新 更多