Silverlight Grid Auto Size not working within canvas - silverlight

How do you make a grid width 100% inside a canvas? Here's some simple XAML but it doesn't work as expected.
<Canvas Background="MediumSlateBlue" Width="Auto" Height="Auto" >
<Grid x:Name="LayoutRoot" MouseMove="MainPage_MouseMove" Background="Beige" >
<TextBlock x:Name="lblDisplay" Height="24" HorizontalAlignment="Right" VerticalAlignment="Top" Width="128" Text="asdf" ></TextBlock>
</Grid>
</Canvas>
I don't understand why my grid doesn't take up as much room as it can get it's hands on! I've even tried adding a single row and column definition with a width of 100*, but still my grid will only take up as much space as the label it contains. The goal is to have a canvas, with a grid child and takes up 100% width and height. This is important because I need the silverlight to resize when the browser resizes.

Canvas lays out its content using absolute positioning. It's much more similar to the way Windows Forms worked in that all elements must have a top, left, width, and height specified.
You can achieve similar functionality by replacing Canvas with a Grid that has no rows/columns defined and use margins to place child elements.

Looks like I found a solution here
http://forums.silverlight.net/forums/t/13415.aspx
I've adjusted my code to automatically resize my grid whenever the content is resized. This will allow me to position elements absolutly using Canvas.LeftProperty and maintain the position of horizontally/vertically aligned elements.
I considered using just a grid as my primary layout, however should the need arise to animate an object, margin cannot be animated. Additionally, setting the margin Left and Top during the mousemove event did not accurately position my element to the cursor position.

Also check to make sure that your form is actually stretching the Silverlight application.
<form id="form1" runat="server" style="height:100%">
<div id="silverlightControlHost">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="clientbin/MyApp.xap"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40818.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40818.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
</form>

Related

My Silverlight app doesnt show changes

It's my first time with SL (but not WPF). Im learning PRISM watching the great videos of MTaulty: http://channel9.msdn.com/blogs/mtaulty/prism--silverlight-part-1-taking-sketched-code-towards-unity
So far so good, I'm with the last video and I'm doing the same things He does in my VS. I'm using SL4 & mvc2 web & prism for sl4.
I Found a problem and I don't know what is going on.
My SL application itself doesnt show any changes. I have a basic shell:
<Grid x:Name="LayoutRoot" Background="Azure">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<ctls:GridSplitter Grid.RowSpan="2" HorizontalAlignment="Right"
VerticalAlignment="Stretch" Width="2"
Background="Black" />
<ctls:GridSplitter Grid.Column="1"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom"
Height="2" Background="Black" />
<Border Background="SkyBlue" CornerRadius="3"
Margin="5" Grid.RowSpan="2">
<ContentControl rgn:RegionManager.RegionName="FolderSelectionRegion"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" />
</Border>
<Border
Background="SkyBlue"
CornerRadius="3"
Margin="5"
Grid.Column="1">
<ContentControl
rgn:RegionManager.RegionName="MailSelectionRegion"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch" />
</Border>
</Grid>
The thing is, I registered a View in the first regionManager, perfect, I registered a second view but it doesnt show... Ok, some bug in someplace... but no.
I realized that the border for the second regionManager is not showing up, ok. I commented the line that register the view (the view is working) and the view is still showing up. I commented the bootstrapper, deleting it from Application_Startup, nothing the view is still showing up (not possible, there is no way that my app knows how to execute the Shell, is all commented out).
In short, I'm sure if I Delete 3 files, the app is still working... I cleaned the solution, deleted the .xap files from the ClientBin... Nothing, the app is still showing up the view and so on. On other words, the app is not reflecting changes on the code.
What's going on?
Thank you.
EDIT: Near one year later...
So, I didn't touch Silverlight since this, but today I wanted to make a very simple app (just a path and textbox) and... Yay my app started to dont show the changes.
I can't reproduce the bug, I don't know what trigger this, but I know that is a problem with ASP.NET MVC.
The project Im talking here, and the project I made today, both were using ASP.NET MVC to launch the SL project.
I uploaded the EmailClient project (just the part we are interested in) to my host: www.foxandxss.net/stuff/EmailClient.rar
Is easy to see the problem. For start, you can see that in Shell.xaml, the LayoutRoot's color is Azure and if you run the application, it will be Green (When I opened today this app, I changed it to Green and worked, but no more changes). If you change the color to another one, it didn't change. If you go to App.xaml.cs and comment the lines that creates and run the bootstrapper (so the app will not run), the app will still opening. Is like the app running is some cache and everychange you make, you wont see it.
I tried deleting the xap from the MVC project, and nothing.
The thing is that if you right click on the SL project and click on "View in browser" you will see the changes (Azure BG or nothing if you commented the boostrapper) but if you run it from the MVC project, nothing.
In the past, I had issues with XAP file caching. If it's the issue, I would inject a dummy parameter next to the xap file path (in this case a timestamp) :
<div id="silverlightControlHost">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<param name="source" value="ClientBin/EmailClient.xap?20110712160700"/>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="4.0.50826.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
If you refresh that parameter on each build, this should invalidate the cache and load the latest xap file.
Samuel has the right idea, however you can get Silverlight to automatically ignore previous timestamps by checking the last write time on the server
<div id="silverlightControlHost">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
<%
const string orgSourceValue = #"ClientBin/SilverlightApp.xap";
string param;
if (System.Diagnostics.Debugger.IsAttached)
param = "<param name=\"source\" value=\"" + orgSourceValue + "\" />";
else
{
string xappath = HttpContext.Current.Server.MapPath(#"") + #"\" + orgSourceValue;
DateTime xapCreationDate = System.IO.File.GetLastWriteTime(xappath);
param = "<param name=\"source\" value=\"" + orgSourceValue + "?ignore=" + xapCreationDate.ToString("yyyy-MM-dd_HH-mm-ss") + "\" />";
}
Response.Write(param);
%>
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="4.0.50401.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50401.0" style="text-decoration:none">
<img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
</a>
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>

How do you change the Silverlight loading screen's background?

I'm trying to avoid the default Silverlight loading screen displaying before my applet and was trying to show a blank coloured background, the same colour as my applet's. The aim is to avoid the jarring white and make it look like it's all part of one app drawing.
I've discovered SplashScreenSource but I'm not sure how to hook that up to just show a single colour background instead of the loading screen. Any suggestions?
Add new XAML file to ASP.NET website, in which Silverlight will be shown.
Replace content of XAML with this:
<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel VerticalAlignment="Center">
<Grid>
<Rectangle x:Name="progressBarBackground" Fill="White" Stroke="Black"
StrokeThickness="1" Height="30" Width="200"></Rectangle>
<Rectangle x:Name="progressBar" Fill="Yellow" Height="28" Width="0">
</Rectangle>
</Grid>
<TextBlock x:Name="progressText" HorizontalAlignment="Center"
Text="0% downloaded ..."></TextBlock>
</StackPanel>
</Grid>
Next, you need to add a JavaScript function to your HTML entry page or ASP.NET.
<script type="text/javascript">
function onSourceDownloadProgressChanged(sender, eventArgs)
{
sender.findName("progressText").Text =
Math.round((eventArgs.progress * 100)) + "% downloaded ...";
sender.findName("progressBar").Width =
eventArgs.progress * sender.findName("progressBarBackground").Width;
}
</script>
To use this splash screen, you need to add the splashscreensource parameter to
identify your XAML splash screen and the onsourcedownloadprogresschanged parameter to
hook up your JavaScript event handler. If you want to react when the download is finished, you
can hook up a different JavaScript event handler using the onsourcedownloadcomplete
parameter:
<object data="data:application/x-silverlight," type="application/x-silverlight-2"
width="100%" height="100%">
<param name="source" value="ClientBin/SplashScreen.xap"/>
<param name="onerror" value="onSilverlightError" />
<param name="background" value="white" />
<param name="splashscreensource" value="SplashScreen.xaml" />
<param name="onsourcedownloadprogresschanged"
value="onSourceDownloadProgressChanged" />
...
</object>
I hope this will help you.

WPF/Silverlight XAML Stretch Text Size to Fit container?

I've just started to play with WPF.
Is it possible to have the size of the text of a Label or TextBlock size itself to fill it's parent container?
Thanks,
Mark
You can use a ViewBox to visually zoom something to fit within its container. The other solutions here work, but they only stretch the control, not its content. The ViewBox will stretch both.
<!-- Big grid, will stretch its children to fill itself -->
<Grid Width="1000" Height="1000">
<!-- The button is stretched, but its text remains teeny tiny -->
<Button>
<!-- The viewbox will stretch its content
to fit the final size of the button -->
<Viewbox
Margin="4"
VerticalAlignment="Stretch"
Height="Auto">
<!-- The textblock and its contents are
stretched to fill its parent -->
<TextBlock
Text="Bartenders" />
</Viewbox>
</Button>
</Grid>
Depends on the parent container
Grid, DockPanel will stretch your control
StackPanel, WrapPanel will leave it to the control to size itself..
Set HorizonalAlignment/VerticalAlignment to "stretch".
Use DockPanel as parent container
<DockPanel>
<TextBlock />
</DockPanel>

WPF: Trigger a content resize with GridSplitter

I'm trying to force a grid/expander to reevaluate whether it needs a scrollbar, as it's showing emptiness.
I'm using this layout:
<Grid>
<toolstrip /> <!-- fixed height row -->
<Scrollviewer> <!-- * height -->
<Grid> <!-- all rows are 'Auto' height -->
<Expander />
<Expander> <!-- this one stretches far too high -->
<WPF Toolkit: DataGrid />
<Expander>
<GridSplitter/>
<Expander />
<Grid>
</Scrollviewer>
<stackpanel /> <!-- fixed height row -->
<Grid>
The DataGrid (WPF Toolkit) is bound to a property when the Window is initialized. Through some investigating, I've realized that when the window is initialized, the columns in the GridView start at about 10 pixels wide, then the content is added, then they're resized based on the sizes in the XAML (All using star widths - eg: 2*). This causes the grid to resize to about 6 times the height it needs to be as the window is showing, then it doesn't spring back and the only way to see what's at the bottom of the window is to either scroll or move the GridSplitter back up to where it should be and resize the Window. I haven't set the VerticalAlignment properties on anything.
So far I've tried all of the following called InvalidateArrange(), InvalidateVisual();, InvalidateMeasure() and UpdateLayout() on the problem expander and InvalidateArrange(), InvalidateScrollInfo(), InvalidateVisual() and UpdateLayout() on the Grid above it but it won't shrink back.
Is there any way I can force it to short of forcing the width of the columns in the DataGrid?
Try setting these properties on the ScrollViewer:
<ScrollViewer CanContentScroll="True"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
... content ...
</ScrollViewer>
If that doesn't work, can you provide a more exact representation of your XAML. Also, taking a look at the ScrollViewer in depth may help.

Filling Browser Window with Silverlight Application

I want my Silverlight app to fill the entire browser window. I've set the plugin object width and height to 100%, and set my LayoutRoot container's height and width to Auto, but still no luck. Any suggestions?
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:Silverlight ID="Silverlight1" runat="server"
Source="~/ClientBin/Client.xap"
MinimumVersion="2.0.30818.0"
AutoUpgrade="true"
Height="100%"
Width="100%">
</asp:Silverlight>
</form>
<UserControl
x:Class="Client.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="Auto"
Width="Auto">
<Grid
x:Name="LayoutRoot"
Background="#084E85"
ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="280" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition Height="Auto" />
<RowDefinition Height="600" />
</Grid.RowDefinitions>
...Remaining content here...
</Grid>
</UserControl>
Disclaimer: I searched for an answer first, finding this thread. However, as you can see by my code that isn't working for me.
First, I don't set the height/width in the user control. Instead, I set the DesignHeight and DesignWidth (in the "http://schemas.microsoft.com/expression/blend/2008" namespace) and I set the alignment to stretch
<UserControl ...
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
d:DesignHeight="1050" d:DesignWidth="1680">
In my HTML, I set the Height and Width to 100% like this...
<div style="height: 100%; width: 100%; position: fixed;">
<asp:Silverlight runat="server" Source="~/ClientBin/My.xap" ID="MyId"
Width="100%" Height="100%" />
</div>
At that point, everything works for me to have it take the entire window.
Remove the Height and Width attributes from the :
<UserControl
x:Class="Client.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
Auto Height and Width with resize the window to fit the content. If you remove the Height and Width attributes, your Silverlight Application will grow to fit the window.
Hmm
I'm thinking your Grid is set-up to be as small as possible (no "star" column or row).
Can you try with one more column and row with a "star" size ?
as other have pointed out, you also need to remove the "auto" sizes, since they auto-size to content.
also try to set a background color on the page, so you see where it actually extends.
If you've got a fairly complex HTML layout and can't rely on fixed positioning then you can make the #silverlightControlHost div resize using the following:
private bool _hasResized;
protected override Size ArrangeOverride(Size finalSize)
{
if (!_hasResized)
{
HtmlPage.Document.GetElementById("silverlightControlHost").SetStyleAttribute("height", finalSize.Height.ToString());
_hasResized = true;
}
return base.ArrangeOverride(finalSize);
}
You can put this inside MainPage.cs or if you have nested UserControls, then the control that requires the most height. I'm also using the following XAML and the default HTML Visual Studio provides
<UserControl ...
VerticalAlignment="Stretch"
Height="Auto"
Width="Auto">
I haven't tested it without these settings, as far as I know Auto is the default.

Resources