Friday, February 11, 2011

Automatic File Download

Troubleshooting automatic file download issue in IE7.0 and later version

Problem: File download using .aspx page or HTTP handler does not work in IE 7.0 and later version.

Solution: If you are storing your files in database and using .aspx page or HTTP handler to write the file to the response, than you must have been bugged by this issue. This is not an error or IE bug but it’s just that the newer version of IE wants to protect its users from malicious contents that could sniff or simply harm your computer or data.
To make it more secure IE has provided option to its users to allow\disallow the automatic downloading of files. This can be set in any kind of security zones. To turn On\Off user needs to perform below steps

Step1) Open IE and click Tools > Internet Options
Step2) Go to Security Tab. Select desired zone and then click Custom Level Button.
Step3) Now look for Downloads > Automatic prompting for file downloads. By default this is disabled due to which any automatic file downloads will be blocked. Enable this feature as shown below.

Note: If you do not want your users to make any changes for above mentioned settings than you can achieve the automatic download but as a tweak you need to have an interim page which requires some user action like button click to download a file.

Animating Grid Column

Troubleshooting InvalidOperationException: DoubleAnimation cannot be used to animate property Width due to incompatible type.

Silverlight has great support for Animation and you might have experienced animating most of the controls on one or the other aspect. But animating ColumnDefinition.Width or RowDefinition.Height properties for Grid control is not straight forward. To achieve this one has to make a tweak.

Problem : InvalidOperationException: DoubleAnimation cannot be used to animate property Width due to incompatible type.

Reason : Width property of grid is not of type double but is of type GridLength. Further GridLength has a property called Value of type Double, but Value is ReadOnly so to change the width or height you have to create a new instance of the GridLength object and set it to the Width Property of the grid.

Solution: To achieve this we simply create a dependency property in our page and in the change event of that property we set the new instance of GridLength to width property of the grid.

[sourcecode language="html"]

<Grid x:Name="myGrid">
<Grid.Resources>
<Storyboard x:Name="myStoryboardC">
<DoubleAnimation From="150" To="0" Duration="00:00:1"
Storyboard.TargetName="myPageName"
Storyboard.TargetProperty="ColumnWidth">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
<Storyboard x:Name="myStoryboardE">
<DoubleAnimation From="0" To="150" Duration="00:00:1"
Storyboard.TargetName= “myPageName"
Storyboard.TargetProperty="ColumnWidth">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseOut"/>
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Column1" Width="150" MaxWidth="250" MinWidth="0">
</ColumnDefinition>
<ColumnDefinition Width="15" MaxWidth="15" MinWidth="15"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

<Rectangle x:Name="myRectangle"
Fill="Blue" Width="200" Height="30" Grid.Column="0"/>

<layoutToolkit:Accordion x:Name="acc" SelectionMode="ZeroOrMore" Grid.Column="0">
<layoutToolkit:AccordionItem Header="hi">
<StackPanel>
<TextBlock Text="1"/>
<TextBlock Text="2"/>
<TextBlock Text="3"/>
</StackPanel>
</layoutToolkit:AccordionItem>
<layoutToolkit:AccordionItem Header="hi" Content="Task 2"/>
<layoutToolkit:AccordionItem Header="hi" Content="Task 3"/>
</layoutToolkit:Accordion>

<Button x:Name="btnEC" Content="&lt;" Grid.Column="1" Click="Button_Click" />

<data:DataGrid x:Name="dataGrid1" Margin="0" Grid.Column="2">
<data:DataGrid.RowDetailsTemplate>
<DataTemplate>
<StackPanel Background="LightBlue">
<StackPanel Orientation="Horizontal">
<TextBlock Text="This item has details." />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Here is some data: " />
<TextBlock Text="{Binding FirstName}" />
<TextBlock Text=" LastName" />
<TextBlock Text="{Binding LastName}" />
</StackPanel>
</StackPanel>
</DataTemplate>
</data:DataGrid.RowDetailsTemplate>
</data:DataGrid>

</Grid>

[/sourcecode]

[sourcecode language="csharp"]

public partial class MainPage : UserControl
{

bool toogle;
public MainPage()
{
InitializeComponent();
this.Name = "myPageName";
}

public static readonly DependencyProperty ColumnWidthProperty = DependencyProperty.Register("ColumnWidth",
typeof(double),
typeof(MainPage),
new PropertyMetadata
(ColumnWidthChanged));
public double ColumnWidth
{
get
{
return (double)GetValue(ColumnWidthProperty);
}
set
{
SetValue(ColumnWidthProperty, value);
}
}

private static void ColumnWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var mainPage = (MainPage)d;
mainPage.Column1.Width = new GridLength((double)e.NewValue);
}

private void Button_Click(object sender, RoutedEventArgs e)
{
if (!toogle)
{
myStoryboardC.Begin();
btnEC.Content = ">";
toogle = !toogle;
}
else
{
myStoryboardE.Begin();
btnEC.Content = "<";
toogle = !toogle;
}
}
}

[/sourcecode]