Sunday, April 24, 2011

ScrollViewer Auto Sizing

Below is the XAML for a portion of the main page of my WP7 app. Note that the height of the ScrollViewer is explicitly set.

        <Canvas Height="224" HorizontalAlignment="Left" Margin="12,24,0,0" Name="CalculatorScreenCanvas" VerticalAlignment="Top" Width="450" Grid.Row="1">
            <TextBlock Canvas.Left="13" Canvas.Top="99" FontSize="25" Height="30" Name="DataInputShadow" Text="2" Width="295" Visibility="Collapsed" />
            <ScrollViewer Canvas.Left="0" Canvas.Top="29" Height="176" Name="CalculatorScreenScrollViewer" Width="456" VerticalContentAlignment="Stretch" VerticalScrollBarVisibility="Visible">
                <Canvas Height="108" Name="CalculatorScreenSubCanvas" Width="455" VerticalAlignment="Stretch">
                    <TextBlock Canvas.Left="10" Canvas.Top="-34" FontSize="25" Height="181" Name="DataInput" Text="tan 25 + cos 45 + 4 cos 46" TextWrapping="Wrap" Width="439" VerticalAlignment="Stretch" />
                    <TextBlock Canvas.Left="10" Canvas.Top="10" FontSize="25" Height="38" Name="CalcCursor" Text="|" Width="8" />
                </Canvas>
            </ScrollViewer>
        </Canvas>

Keeping the Bottom of a Textblock Displayed, in a ScrollViewer

The following method checks to see if text in a TextBlock which is dynamically updated, wraps around, and occupies a new line. The method also invokes the ScrollToVerticalOffset method of the ScrollViewer control, if the above happens. The following are 3 versions of the method, based on suggested solutions I received:

Version 1 of method:

        private void UpdateDisplay()
        {
            // Height of text in text block
            float DataInputHeight = (float)MainAppPage_cls.DataInput.ActualHeight;
           
            if (TextPreviousHeight_cls == 0)
            {
                TextPreviousHeight_cls = DataInputHeight;
            }
            else
            {
                if (DataInputHeight > TextPreviousHeight_cls)
                {
                    MainAppPage_cls.CalculatorScreenScrollViewer.ScrollToVerticalOffset(DataInputHeight);
                    TextPreviousHeight_cls = DataInputHeight;
                }
            }
        }

Version 2 of method:


        private void UpdateDisplay()
        {
            // Height of text in text block
            float DataInputHeight = (float)MainAppPage_cls.DataInput.ActualHeight;
           
            if (TextPreviousHeight_cls == 0)
            {
                TextPreviousHeight_cls = DataInputHeight;
            }
            else
            {
                if (DataInputHeight > TextPreviousHeight_cls)
                {
                    MainAppPage_cls.CalculatorScreenScrollViewer.UpdateLayout();
                    MainAppPage_cls.CalculatorScreenScrollViewer.ScrollToVerticalOffset(MainAppPage_cls.CalculatorScreenSubCanvas.ActualHeight);
                    TextPreviousHeight_cls = DataInputHeight;
                }
            }
        }

Version 3 of method:


        private void UpdateDisplay()
        {
            // Height of text in text block
            float DataInputHeight = (float)MainAppPage_cls.DataInput.ActualHeight;
           
            if (TextPreviousHeight_cls == 0)
            {
                TextPreviousHeight_cls = DataInputHeight;
            }
            else
            {
                if (DataInputHeight > TextPreviousHeight_cls)
                {
                    MainAppPage_cls.CalculatorScreenScrollViewer.UpdateLayout();
                    MainAppPage_cls.CalculatorScreenScrollViewer.ScrollToVerticalOffset(DataInputHeight);
                    TextPreviousHeight_cls = DataInputHeight;
                }
            }
        }

Tuesday, April 12, 2011

Problem Assigning Button, Background Property In Windows Phone 7

I'm creating a calculator program. One of the buttons on the calculator, toggles two sets of keys across the 1st row of buttons. E.g. by default, the 1st row of buttons display the following function keys (in dark gray):

x^2, x^n, sqrt, pi, (, )

When I press the toggle button, the 1st row of buttons display the following function keys (in green):

FRAC, %, P->R, R->P, nPr, nCr

Pressing the toggle key further, toggles both sets of function keys across the 1st row of buttons.

To achieve the above, I essentially assign each button's Content and Background properties, their respective display text and color. The above works fine in my code if I click on the toggle button several times. If I click any button on the calculator keyboard, except one in the top row, then press the toggle button, my code works fine as well. However, if I click any button in the top row, then click the toggle button, the background color of the top buttons unpredictably display one of the two colors I assign (e.g. green, when it should display gray).

Below is a simplified version of my code which also shows the problem. (The example code uses background colors green and black, instead of green and dark gray.)

   public partial class MainPage : PhoneApplicationPage
    {
        private bool SciCalcFirstKeySetDisplayed_bln = true;
       
        private void ToggleScientificCalcButtons()
        {
            if (SciCalcFirstKeySetDisplayed_bln)
            {
  // Buttons at top of screen
                Button_0_0_btn.Content = "FRAC";
                Button_0_0_btn.Background = new SolidColorBrush(Colors.Green);
                Button_0_1_btn.Content = "%";
                Button_0_2_btn.Content = "P" + "\u2192" + "R";
                Button_0_2_btn.Background = new SolidColorBrush(Colors.Green);
                Button_0_3_btn.Content = "R" + "\u2192" + "P";
                Button_0_3_btn.Background = new SolidColorBrush(Colors.Green);
                Button_0_4_btn.Content = "nPr";
                Button_0_4_btn.Background = new SolidColorBrush(Colors.Green);
                Button_0_5_btn.Content = "nCr";
                Button_0_5_btn.Background = new SolidColorBrush(Colors.Green);
  // Toggle button
                Button_3_5_btn.Content = "1st";
            }
            else
            {
   // Buttons at top of screen
               Button_0_0_btn.Content = "x" + "\u00B2";
                Button_0_0_btn.Background = new SolidColorBrush(Colors.Black);
                Button_0_1_btn.Content = "x" + "\u207F";
                Button_0_2_btn.Content = "\u221A";
                Button_0_2_btn.Background = new SolidColorBrush(Colors.Black);
                Button_0_3_btn.Content = "\u03c0";
                Button_0_3_btn.Background = new SolidColorBrush(Colors.Black);
                Button_0_4_btn.Content = "(";
                Button_0_4_btn.Background = new SolidColorBrush(Colors.Black);
                Button_0_5_btn.Content = ")";
                Button_0_5_btn.Background = new SolidColorBrush(Colors.Black);
   // Toggle button
               Button_3_5_btn.Content = "2nd";
            }
            SciCalcFirstKeySetDisplayed_bln = !SciCalcFirstKeySetDisplayed_bln;
        }

 // Click Event Handler for toggle button
        private void Button_3_5_btn_Click(object sender, RoutedEventArgs e)
        {
            ToggleScientificCalcButtons();
        }
    }

I appreciate any help someone can provide me.