locked
Having a button change RowDefinition height - nonprogrammer's version RRS feed

  • Question

  • Hello - I added a reply with a followup question to the previous thread about using VisualStates to dynamically change RowDefinition height in a grid, but realized that it might be skipped over because the question in that thread is marked as answered. So here's my question:

    In that thread, it was stated that you can't use VisualStates to record different versions of a grid with different row heights, as you might need to have a button that expands and restores a panel. In that thread, a couple of lines of C# code were given as the way to dynamically manipulate the row heights within a layout grid. However, as a nonprogrammer who relies mostly on visual states, storyboards and the Blend UI to create my interaction, I have no idea where to put those lines of C# code or what other problems could crop up once I do. Are there any good suggestions for a nonprogrammer to create a button that changes the RowDefinition heights within a layout grid?

    I am using Blend 4 to create a WPF project, incidentally.

    Thanks,

    B

    Wednesday, October 3, 2012 4:42 PM

Answers

  • I got to playing with this a bit more after posting and the following is a way to animate the gridlengths...

    First I changed the xaml of the first row ... I gave the row a name of "row1".  I also changed the GridUnitType to a pixel value of 100.

    <Grid.RowDefinitions>
    	<RowDefinition x:Name="row1" Height="100"/>
    	<RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    And the code-behind...

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    
    //Added the following "using" statement.
    using System.Windows.Threading;
    
    namespace WpfApplication44
    {
    	public partial class MainWindow : Window
    	{
    		
    		//Created a timer.
    		DispatcherTimer dt = new DispatcherTimer();
    		
    		public MainWindow()
    		{
    			this.InitializeComponent();
    		}
    		
    		private void upButton_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			//myGrid.RowDefinitions[0].Height = new GridLength(1, GridUnitType.Star);
    			
    			
    			//Added the stop just in case it was in the middle of a down animation.
    			dt.Stop();
    			
    			dt = new DispatcherTimer();
    			int counter = 0;
    			
    			// The timer ticks every 10/1000 of a second and each tick reduces the 
    			// row height by 2.
    			
    			dt.Tick += delegate
    			{
    				counter++;
    				if (row1.ActualHeight > 100) 
    				{
    					double a = row1.ActualHeight - 2;
    					row1.Height = new GridLength(a, GridUnitType.Pixel);
    				}
    				else
    					dt.Stop();
    			};
    			dt.Interval = new TimeSpan(0, 0, 0, 0, 10);
    			dt.Start();
    		}
    
    		private void downButton_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			//myGrid.RowDefinitions[0].Height = new GridLength(2, GridUnitType.Star);
    			
    			// Just opposite of the up animation
    			dt.Stop();
    			
    			dt = new DispatcherTimer();
    			int counter = 0;
    			
    			dt.Tick += delegate
    			{
    				counter++;
    				if (row1.ActualHeight < 300)
    				{
    					double a = row1.ActualHeight + 2;
    					row1.Height = new GridLength(a, GridUnitType.Pixel);
    				}
    				else
    					dt.Stop();
    			};
    			dt.Interval = new TimeSpan(0, 0, 0, 0, 10);
    			dt.Start();
    		}
    	}
    }

    ~Christine

    I stuck the sample project on my SkyDrive so you could play with it... http://sdrv.ms/VhGEpc


    My Gallery


    • Edited by Christine L. _ Wednesday, October 3, 2012 7:53 PM
    • Marked as answer by BMeyerMcK Thursday, October 4, 2012 5:32 PM
    Wednesday, October 3, 2012 7:44 PM

All replies

  • Hello BMeyerMcK.

    To create the click event or code for your button....

    1.  Select it in the Objects and Timeline panel or on your artboard.

    2.  Click the "Events" button in the top-right of the "Properties" tab.  A small button with a lightning bolt.

    3.  The first event listed should be "Click".  Double-Click in that box and it will take you to the code-behind file and start the code for you.  Something like this if you are using C#.

    private void myButton_Click(object sender, System.Windows.RoutedEventArgs e)
    {
    	// TODO: Add event handler implementation here.
    }

    The code will go between the 2 curly brackets.  The comment showing between those you can delete. 

    Here is a sample...

    <Window
    	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" mc:Ignorable="d"
    	x:Class="WpfApplication44.MainWindow"
    	x:Name="Window"
    	Title="MainWindow"
    	Width="640" Height="480">
    
    	<Grid x:Name="LayoutRoot">
    		<Grid x:Name="myGrid">
    			<Grid.RowDefinitions>
    				<RowDefinition Height="1*"/>
    				<RowDefinition Height="1*"/>
    			</Grid.RowDefinitions>
    			<Rectangle Fill="Blue" Grid.Row="0" Stroke="Black"/>
    			<Rectangle Fill="Red" Grid.Row="1" Stroke="Black"/>
    			<StackPanel Margin="0" Orientation="Horizontal" d:LayoutOverrides="Height" HorizontalAlignment="Left" VerticalAlignment="Top">
    				<Button x:Name="upButton" Width="75" Height="30" Content="Up" d:LayoutOverrides="Height" Margin="5" Click="upButton_Click"/>
    				<Button x:Name="downButton" Width="75" Height="30" Content="Down" d:LayoutOverrides="Height" Margin="5" Click="downButton_Click"/>
    			</StackPanel>
    		</Grid>
    	</Grid>
    </Window>

    I created an Up and Down button with events attached to each.  Here is the code-behind...

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    
    namespace WpfApplication44
    {
    	public partial class MainWindow : Window
    	{
    		public MainWindow()
    		{
    			this.InitializeComponent();
    		}
    
    		private void upButton_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			myGrid.RowDefinitions[0].Height = new GridLength(1, GridUnitType.Star);
    		}
    
    		private void downButton_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			myGrid.RowDefinitions[0].Height = new GridLength(2, GridUnitType.Star);
    		}
    	}
    }

    myGrid.RowDefinitions[0] =  the grid I named "myGrid" and it is the first row in that grid.

    myGrid.RowDefinitions[1] would be the second row in the grid.

    By assigning the first grid a value of 2*, on the down event, I'm telling it to take up 2/3 of the grid.

    By assigning both to 1 or equal amounts, they take up 50% each. 

    There is another example from a past post I was involved with here... http://social.expression.microsoft.com/Forums/en-US/blend/thread/d35325cd-399f-428d-95d3-e6a2eae45d84

    There were 2 examples actually.  One using code and a xaml only solution.

    This link explains a bit about GridLength... http://msdn.microsoft.com/en-us/library/system.windows.gridlength.aspx

    Let us know if that helps or if you have any more questions.

    ~Christine


    My Gallery




    Wednesday, October 3, 2012 6:51 PM
  • I got to playing with this a bit more after posting and the following is a way to animate the gridlengths...

    First I changed the xaml of the first row ... I gave the row a name of "row1".  I also changed the GridUnitType to a pixel value of 100.

    <Grid.RowDefinitions>
    	<RowDefinition x:Name="row1" Height="100"/>
    	<RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    And the code-behind...

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    
    //Added the following "using" statement.
    using System.Windows.Threading;
    
    namespace WpfApplication44
    {
    	public partial class MainWindow : Window
    	{
    		
    		//Created a timer.
    		DispatcherTimer dt = new DispatcherTimer();
    		
    		public MainWindow()
    		{
    			this.InitializeComponent();
    		}
    		
    		private void upButton_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			//myGrid.RowDefinitions[0].Height = new GridLength(1, GridUnitType.Star);
    			
    			
    			//Added the stop just in case it was in the middle of a down animation.
    			dt.Stop();
    			
    			dt = new DispatcherTimer();
    			int counter = 0;
    			
    			// The timer ticks every 10/1000 of a second and each tick reduces the 
    			// row height by 2.
    			
    			dt.Tick += delegate
    			{
    				counter++;
    				if (row1.ActualHeight > 100) 
    				{
    					double a = row1.ActualHeight - 2;
    					row1.Height = new GridLength(a, GridUnitType.Pixel);
    				}
    				else
    					dt.Stop();
    			};
    			dt.Interval = new TimeSpan(0, 0, 0, 0, 10);
    			dt.Start();
    		}
    
    		private void downButton_Click(object sender, System.Windows.RoutedEventArgs e)
    		{
    			//myGrid.RowDefinitions[0].Height = new GridLength(2, GridUnitType.Star);
    			
    			// Just opposite of the up animation
    			dt.Stop();
    			
    			dt = new DispatcherTimer();
    			int counter = 0;
    			
    			dt.Tick += delegate
    			{
    				counter++;
    				if (row1.ActualHeight < 300)
    				{
    					double a = row1.ActualHeight + 2;
    					row1.Height = new GridLength(a, GridUnitType.Pixel);
    				}
    				else
    					dt.Stop();
    			};
    			dt.Interval = new TimeSpan(0, 0, 0, 0, 10);
    			dt.Start();
    		}
    	}
    }

    ~Christine

    I stuck the sample project on my SkyDrive so you could play with it... http://sdrv.ms/VhGEpc


    My Gallery


    • Edited by Christine L. _ Wednesday, October 3, 2012 7:53 PM
    • Marked as answer by BMeyerMcK Thursday, October 4, 2012 5:32 PM
    Wednesday, October 3, 2012 7:44 PM
  • That looks incredibly helpful - I'll try it shortly. Thanks!
    Wednesday, October 3, 2012 8:50 PM
  • Worked like a charm. Thanks so much!
    Thursday, October 4, 2012 5:32 PM