Thursday, February 28, 2013

Silverlight layout resizing

On my current project, we need the pages to be able to resize and display the controls in the most efficient way depending on the current size the user is viewing the application. 

I found one great way here - where using LayoutRoot.SizeChanged and LayoutRoot.LayoutUpdated did a great job in updating the page and making sure that it filled out the screen as expected. What wasn't expected was how it did not work in development for some reason. According to what I was told, it kept looping with another function used and the page wouldn't stop reloading.

Hopefully, I'll be able to get this other way to work, I have mixed the LayoutRoot.SizeChanged with the App.Current.Host.ContentResized where the page will now look to see if the overall browser window has been resized and not look towards the application's main page. Hopefully this will work. (I am so crossing my fingers)

So, the updated way I have it now is:


public MyPage()
{
      InitializeComponent();
    
   // this function is to make sure the controls are the correct size when the page is loading up
     this.Loaded += new RoutedEventHandler(startupLayoutSize);

    // this has the page checking if the overall window has resized, if so then update the sizes of the controls
     App.Current.Host.Content.Resized += new EventHandler(Content_Resized);

// below checks the page size also but it depends on if the overall LayoutRoot of the page has changed
     LayoutRoot.SizeChanged += LayoutRoot_SizeChanged;
}


// even though I am not checking if the main page itself has changed size, I am wanting to
// know the ActualHeight and ActualWidth of the content frame this page is displayed in
MainPage mainPage = (MainPage)Application.Current.RootVisual;


void Content_Resized(object sender, EventArgs e)
{
     Frame pageContainer = mainPage.FindName("PageFrame") as Frame;
     var pageHeight = pageContainer.ActualHeight;
     var pageWidth = pageContainer.ActualWidth;

     this.LayoutRoot.Height = pageHeight;
     this.LayoutRoot.Width = pageWidth;
     
     // many of the controls are in this border and I want them sized proportionally to this border
     var myBorder = pageSideBorder.ActualWidth;

     // I have it set to center horizontally, so when I set the width to 10 less than the actual width
     // of the border, it has the visual effect of adding padding to each side.
     // this does NOT scale the control like ScaleX and ScaleY in a RenderTransform
     controlOne.VerticalAlignment =  VerticalAlignment.Center;
     controlOne.HorizontalAlignment = HorizontalAlignment.Center;
     controlOne.Width = myBorder - 10;
}

     bool updating;
     int layoutUpdated, sizeChanged;
 
// this function also sizes the same controls, but does it when the page loads so they are seen correctly
// when the user first views the page
void startupLayoutSize(object sender, RoutedEventArgs e)
{
     var myBorder = pageSideBorder.ActualWidth;

     controlOne.VerticalAlignment =  VerticalAlignment.Center;
     controlOne.HorizontalAlignment = HorizontalAlignment.Center;
     controlOne.Width = myBorder - 10;
}

// this one does check to see if the size of the LayoutRoot in the main page has changed, but
// it does not look at if the layout is updating
public void LayoutRoot_SizeChanged(object sender, SizeChangedEventArgs e)
{
      MainPage chartMainPage = sender as MainPage;

     if (!updating)
     {
        ++sizeChanged;
        updateContent()
     }
}

// I have the same function but without the EventArgs e
// I will try later to see if I need to do this, but for now it works and that is half of my battle. 
// OK, right now it IS the battle.
private void updateContent( )
{
     Frame pageContainer = mainPage.FindName("PageFrame") as Frame;
     var pageHeight = pageContainer.ActualHeight;
     var pageWidth = pageContainer.ActualWidth;

     this.LayoutRoot.Height = pageHeight;
     this.LayoutRoot.Width = pageWidth;
     
     // many of the controls are in this border and I want them sized proportionally to this border
     var myBorder = pageSideBorder.ActualWidth;

     // I have it set to center horizontally, so when I set the width to 10 less than the actual width
     // of the border, it has the visual effect of adding padding to each side.
     // this does NOT scale the control like ScaleX and ScaleY in a RenderTransform
     controlOne.VerticalAlignment =  VerticalAlignment.Center;
     controlOne.HorizontalAlignment = HorizontalAlignment.Center;
     controlOne.Width = myBorder - 10;
}

Now, hopefully this "solution" will work - and then I have this as reference for later. If not - then this is a reference of what I started with and was still an oops moment. (and will be updated)

Monday, February 25, 2013

Error 2103 Revisited

More accurately, it revisited me again.

Every time I search for another answer, I usually get the setting for the startup - and I always check and mine has always been ok. Very frustrating.

This time, it was an error in my resource dictionary (XAML) on one of my styles. There were elements the style was bound to that had been removed.

This gave me the "Catastrophic Error" and when trying to run I got the dreaded 2103 code.

I remembered the last style I had added, and looked over that since Silverlight ran right before the changes were saved. The elements of the style had that squiggly line (in VisualStudio 2010 - it's one of my "technical" terms) that let me know where the error was.

Thursday, February 7, 2013

General Silverlight Chart Construction


Using the default Microsoft Style for the Charts and will be updating with expanded information as time allows.

The current layout is rough, but I wanted to get a start on this since I know I will be adding a lot as I get the time to compile my notes and create the images to help. 
 
<!--
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
-->

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:datavis="clr-namespace:System.Windows.Controls.DataVisualization"
    xmlns:charting="clr-namespace:System.Windows.Controls.DataVisualization.Charting"
    xmlns:chartingprimitives="clr-namespace:System.Windows.Controls.DataVisualization.Charting.Primitives">

    <Style TargetType="charting:Chart">
        <Setter Property="BorderBrush" Value="Black"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="IsTabStop" Value="False"/>
        <Setter Property="Padding" Value="10"/>
 
 
 
This is the default palette used in the standard charts. As a series is added, the chart will go to the next color (example: Series[0] will be Blue, and Series [0] will be Red. The image above is a quick graphic reference of the default colors.
. 
        <Setter Property="Palette">
            <Setter.Value>
                <datavis:ResourceDictionaryCollection>
                    <!-- Blue -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1"  
                                             Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FFB9D6F7"/>
                            <GradientStop Color="#FF284B70" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Red -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1" 
                                             Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FFFBB7B5"/>
                            <GradientStop Color="#FF702828" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Light Green -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1" 
                                             Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FFB8C0AC"/>
                            <GradientStop Color="#FF5F7143" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Yellow -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1"  
                                             Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FFFDE79C"/>
                            <GradientStop Color="#FFF6BC0C" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Indigo -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1" 
                                                                                                       Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FFA9A3BD"/>
                            <GradientStop Color="#FF382C6C" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Magenta -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1" 
                                             Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FFB1A1B1"/>
                            <GradientStop Color="#FF50224F" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Dark Green -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1"  
                                             Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FF9DC2B3"/>
                            <GradientStop Color="#FF1D7554" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Gray Shade -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1"  
                                             Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FFB5B5B5"/>
                            <GradientStop Color="#FF4C4C4C" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Blue -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1"  
                                                                                                        Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FF98C1DC"/>
                            <GradientStop Color="#FF0271AE" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Brown -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1"  
                                             Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FFC1C0AE"/>
                            <GradientStop Color="#FF706E41" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Cyan -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1"  
                                              Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FFADBDC0"/>
                            <GradientStop Color="#FF446A73" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Special Blue -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1" 
                                             Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FF2F8CE2"/>
                            <GradientStop Color="#FF0C3E69" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Gray Shade 2 -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1" 
                                             Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FFDCDCDC"/>
                            <GradientStop Color="#FF757575" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Gray Shade 3 -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1" 
                                             Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FFF4F4F4"/>
                            <GradientStop Color="#FFB7B7B7" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                    <!-- Gray Shade 4 -->
                    <ResourceDictionary>
                        <RadialGradientBrush x:Key="Background" GradientOrigin="-0.1,-0.1"  
                                              Center="0.075,0.015" RadiusX="1.05" RadiusY="0.9">
                            <GradientStop Color="#FFF4F4F4"/>
                            <GradientStop Color="#FFA3A3A3" Offset="1"/>
                        </RadialGradientBrush>
                        <Style x:Key="DataPointStyle" TargetType="Control">
                            <Setter Property="Background" Value="{StaticResource Background}"/>
                        </Style>
                        <Style x:Key="DataShapeStyle" TargetType="Shape">
                            <Setter Property="Stroke" Value="{StaticResource Background}" />
                            <Setter Property="StrokeThickness" Value="2" />
                            <Setter Property="StrokeMiterLimit" Value="1" />
                            <Setter Property="Fill" Value="{StaticResource Background}" />
                        </Style>
                    </ResourceDictionary>
                </datavis:ResourceDictionaryCollection>
            </Setter.Value>
        </Setter>
 
 
Below starts the default styles for each element of the chart. The can also be set individually as another style if you want to change one or two elements only.  
 
<Setter Property="TitleStyle">
            <Setter.Value>
                <Style TargetType="datavis:Title">
                    <Setter Property="FontSize" Value="16"/>
                    <Setter Property="HorizontalAlignment" Value="Center"/>
                    <Setter Property="Margin" Value="0,10,0,10"/>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="LegendStyle">
            <Setter.Value>
                <Style TargetType="datavis:Legend">
                    <Setter Property="Margin" Value="15,0,15,0"/>
                    <Setter Property="VerticalAlignment" Value="Center"/>
                    <Setter Property="BorderBrush" Value="#FFDBDBDB"/>
                    <Setter Property="Background">
                        <Setter.Value>
                            <LinearGradientBrush EndPoint="0.442,0.005" StartPoint="0.558,0.995">
                                <GradientStop Color="#FFDBDBDB"/>
                                <GradientStop Color="#FFFFFFFF" Offset="1"/>
                            </LinearGradientBrush>
                       </Setter.Value>
                    </Setter>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="ChartAreaStyle">
            <Setter.Value>
                <Style TargetType="Panel">
                    <Setter Property="MinWidth" Value="100"/>
                    <Setter Property="MinHeight" Value="75"/>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="PlotAreaStyle">
            <Setter.Value>
                <Style TargetType="Grid">
                    <Setter Property="Background">
                        <Setter.Value>
                            <LinearGradientBrush EndPoint="0.457,0.296" StartPoint="0.459,1.296">
                                <GradientStop Color="#FFCBCBCB"/>
                                <GradientStop Color="#FFFFFFFF" Offset="1"/>
                            </LinearGradientBrush>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Setter.Value>
        </Setter>
 
This is the main template, layout of the Silverlight chart. The image above gives a simplified graphic representation of how the chart is assembled.
  
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="charting:Chart">
                    <Border
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        Padding="{TemplateBinding Padding}">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>

                            <datavis:Title
                                Content="{TemplateBinding Title}"
                                Style="{TemplateBinding TitleStyle}"/>

                            <!-- Use a nested Grid to avoid possible clipping behavior resulting from ColumnSpan+Width=Auto -->
                            <Grid Grid.Row="1" Margin="0,15,0,15">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>

                                <datavis:Legend x:Name="Legend" 
                                    Header="{TemplateBinding LegendTitle}"
                                    Style="{TemplateBinding LegendStyle}"
                                    Grid.Column="1"/>
                                <chartingprimitives:EdgePanel x:Name="ChartArea" Style="{TemplateBinding ChartAreaStyle}">
                                    <Grid Canvas.ZIndex="-1" Style="{TemplateBinding PlotAreaStyle}" />
                                    <Border Canvas.ZIndex="10" BorderBrush="#FF919191" BorderThickness="1" />
                                </chartingprimitives:EdgePanel>
                            </Grid>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>