C# 如何在Xaml中使用折叠控件调整UI?

C# 如何在Xaml中使用折叠控件调整UI?,c#,xaml,windows-phone-8,C#,Xaml,Windows Phone 8,我的项目是WP8.1,我正在使用Silverlight。 在这个项目中,我有两个矩形,一个蓝色的和一个红色的。我希望每一个都占屏幕宽度的50%,所以我做了如下: <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions

我的项目是WP8.1,我正在使用Silverlight。 在这个项目中,我有两个矩形,一个蓝色的和一个红色的。我希望每一个都占屏幕宽度的50%,所以我做了如下:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Rectangle Grid.Column="0" Fill="Blue" Visibility="{Binding BlueRectVisibility}" />
    <Rectangle Grid.Column="1" Fill="Red" Visibility="{Binding RedRectVisibility}"/>
</Grid>

有时,其中一个矩形可以通过绑定将其可见性设置为折叠。我想要的是另一个占据所有宽度。 使用该Xaml,可见矩形只占屏幕的一半

将ColumnDefinitions更改为Auto不起作用,因为网格不再占据100%的屏幕宽度


你能解释一下如何创建一个“动态”用户界面吗?

我认为问题的根源在于你将网格的列定义为50%,所以一旦建立了这个值,那么改变矩形的可见性将不会有任何区别。我使用WPF制作了这个小POC(不确定是否所有命令都转换为Silverlight,但您可以试试)。基本上,我专注于搞乱列的宽度,而不是矩形的可见性

在xaml文件中:

<Window x:Class="CollapsibleRegion.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:CollapsibleRegion"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Window.InputBindings>
    <KeyBinding Modifiers="Ctrl" Key="B" Command="{Binding ToggleWidthCommand}" CommandParameter="Blue"/>
    <KeyBinding Modifiers="Ctrl" Key="R" Command="{Binding ToggleWidthCommand}" CommandParameter="Red"/>
</Window.InputBindings>
<Grid>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Name="blueColumn" Width="{Binding BlueColumnWidth}" />
            <ColumnDefinition x:Name="redColumn" Width="{Binding RedColumnWidth}" />
        </Grid.ColumnDefinitions>
        <Rectangle Grid.Column="0" Fill="Blue" />
        <Rectangle Grid.Column="1" Fill="Red" />
    </Grid>
</Grid>
</Window>
最后,对于ToggleWidthCommand.cs,添加以下内容:

public class ToggleWidthCommand : ICommand
{
    private MainWindow parent;

    public ToggleWidthCommand(MainWindow parent)
    {
        this.parent = parent;
    }

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        var blueOrRed = (string)parameter;

        if (blueOrRed == "Blue")
        {
            if (this.parent.BlueColumnWidth.Value == 0)
                this.parent.BlueColumnWidth = new System.Windows.GridLength(5, System.Windows.GridUnitType.Star);
            else
                this.parent.BlueColumnWidth = new System.Windows.GridLength(0, System.Windows.GridUnitType.Pixel);
        }
        if (blueOrRed == "Red")
        {
            if (this.parent.RedColumnWidth.Value == 0)
                this.parent.RedColumnWidth = new System.Windows.GridLength(5, System.Windows.GridUnitType.Star);
            else
                this.parent.RedColumnWidth = new System.Windows.GridLength(0, System.Windows.GridUnitType.Pixel);
        }
    }
}

这只是一个概念证明,显然有更有效/更干净/可扩展的方法来实现此行为,但我只是尝试快速做出响应,向您展示如何实现此行为。希望它对你有用

自动不起作用的原因是布局如下所示:

  • 页面
    :嘿
    网格
    ,你想要多大
  • 网格
    :Dunno,让我问
    列定义
    。你想要多大
  • 列定义
    :哎呀,我不确定;我需要询问
    矩形
    。嘿
    矩形
    ,您需要多少空间
  • Rectange
    :呃,我真的不在乎
  • ColumnDefinition
    :然后为零
  • 等等,把链条往后拉
  • 因此,您将得到一个零宽度的列。解决方案是动态绑定宽度。具有正确的方法,但以下是Windows Phone 8.1的简化版本:

    XAML

    <StackPanel>
      <Grid Height="100">
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="{Binding FirstColumnWidth}" />
          <ColumnDefinition Width="{Binding SecondColumnWidth}"/>
        </Grid.ColumnDefinitions>
        <Rectangle VerticalAlignment="Stretch" 
          HorizontalAlignment="Stretch" Fill="Blue" />
        <Rectangle VerticalAlignment="Stretch" 
          HorizontalAlignment="Stretch" Fill="Red" Grid.Column="1"/>
      </Grid>
      <Button Content="toggle column width" Click="ToggleColWidth"/>
    </StackPanel>
    
    使用这种方法,您甚至不需要更改矩形的可见性

    <StackPanel>
      <Grid Height="100">
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="{Binding FirstColumnWidth}" />
          <ColumnDefinition Width="{Binding SecondColumnWidth}"/>
        </Grid.ColumnDefinitions>
        <Rectangle VerticalAlignment="Stretch" 
          HorizontalAlignment="Stretch" Fill="Blue" />
        <Rectangle VerticalAlignment="Stretch" 
          HorizontalAlignment="Stretch" Fill="Red" Grid.Column="1"/>
      </Grid>
      <Button Content="toggle column width" Click="ToggleColWidth"/>
    </StackPanel>
    
    public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged
    {
      GridLength firstWidth;
      GridLength secondWidth;
    
      public MainPage()
      {
        firstWidth = secondWidth = new GridLength(1, GridUnitType.Star);
        DataContext = this;
        InitializeComponent();
      }
    
      void RaisePropertyChanged([CallerMemberName] string name = "")
      {
        var handler = PropertyChanged;
        if (handler != null)
          handler(this, new PropertyChangedEventArgs(name));
      }
      public event PropertyChangedEventHandler PropertyChanged;
    
      public GridLength FirstColumnWidth
      {
        get { return firstWidth; }
        set { firstWidth = value; RaisePropertyChanged(); }
      }
    
      public GridLength SecondColumnWidth
      {
        get { return secondWidth; }
        set { secondWidth = value; RaisePropertyChanged(); }
      }
    
      private void ToggleColWidth(object sender, RoutedEventArgs e)
      {
        if (FirstColumnWidth.GridUnitType == GridUnitType.Star)
        {
          FirstColumnWidth = new GridLength(0, GridUnitType.Pixel);
          SecondColumnWidth = new GridLength(1, GridUnitType.Star);
        }
        else
        {
          FirstColumnWidth = SecondColumnWidth = new GridLength(1, GridUnitType.Star);
        }
      }
    }