Blog


How to install Windows 8 in a virtualized environment

posted Sep 17, 2011, 8:29 AM by Rene Rasmussen   [ updated Sep 17, 2011, 8:35 AM ]

I like to try out the Windows 8 Developer Preview, but don’t want “sacrifice” my main computer, so I looked for guidelines on installing the Windows 8 Developer preview in a virtualized environment and found a number of solutions.

Here is what found...

VMWare

VirtualBox

Virtual Hard Disk

...have fun :)

/René

Silverlight – Unable to databind Text on the Run Element

posted Jun 8, 2010, 12:54 PM by Rene Rasmussen

I love the Run element as it provides the ability to align text pieces with different formatting. This works perfect with constant text strings, but when you try to data bind to the Text property on Run it fails.

There are several ideas posted on web (http://forums.silverlight.net/forums/p/13637/53097.aspx) on how to make the Run element support data binding to Text but I have found none of them to be successful.

So if you are in the same situation as was, looking for a solution on how to bind to the Text property on Run, I suggest you stop looking and just set the Text property from code behind. That’s what I ended up doing.
 
By the way, this is only an issue with Silverlight 3 and lower, the issue is solved with Silverlight 4, so if you can upgrade to Silverlight 4, go ahead.

Export DataGrid to Excel - Silverlight 3

posted May 4, 2010, 12:16 PM by Rene Rasmussen   [ updated May 10, 2010, 1:50 PM ]

I meet a lot of requests from developers who want to export their data presented in a Silverlight grid to Excel. Well, actually it is the developers who meet a lot of request from the users to export data from data grid to Excel.  The best approach is normally to convert “the original data”. That is, use the data source when you export data, don’t use the data from found in the data grid.

But there are several arguments to use the data grid as data source. First of all, it is possible to implement an “automatic” exporter method which will export almost any data grid to Excel. This is a fast way to support “Export to Excel” from “all” data grids and it does provide an Excel document which has the same column order and sort order as the user has defined in the data grid. 

Silverlight 3 is working in a limited sandbox which does enable us to access Excel and generate a true Excel document, but we can create a simple ‘,’ separated file which Excel can parse and that’s what I will do in this demo.

There are quite a lot of pit falls to be aware of when implementing a generic method for exporting data to Excel, but first let’s have a look at the overall design .
private void ConvertDataGridToExcel(DataGrid grid)
{
  StringBuilder sb = new StringBuilder();

  // add headers
  foreach (var col in grid.Columns)
  {
    sb.Append(AddHeaderItem(col));
  }

  // add data
  foreach (var row in grid.ItemsSource)
  {
    foreach (var col in grid.Columns)
    {
      sb.Append(AddDataItem(col, row));
    }
  }

  SaveToCsvFile(sb);
}
This is pretty straight forward, so let’s look at the pitfalls.
The user is normally allowed to reorder the columns in the data grid and the exported file should present data as it organized by the user. Solution:
foreach (var column in grid.Columns.OrderBy(c => c.DisplayIndex).ToList())
The data grid is virtualized and only the data currently visible is presented found when enumerating the ItemSource. Therefore we scroll to the last item in each row before trying to load the item.Solution:
grid.ScrollIntoView(row, grid.Columns.OrderBy(c => c.DisplayIndex).Last());
Parsing the data source depends on the data source type. See implementation below for details on implementation.
The full implementation is shown here.
private void CreateCsvFile(object sender, RoutedEventArgs e)
{
  var sfd = new SaveFileDialog();
  sfd.DefaultExt = ".csv";
  sfd.Filter = "Excel-CSV Files|*.csv";
  sfd.FilterIndex = 1;
  if (true == sfd.ShowDialog())
  {
    using (var stream = sfd.OpenFile())
    using (var sw = new StreamWriter(stream))
    {
      sw.Write(ConvertDataGridToCsv(MyDataGrid, true));
    }
  }
}

private string ConvertDataGridToCsv(DataGrid grid, bool addHeaders)
{
  var sb = new StringBuilder();
  if (addHeaders)
  {
    foreach (var column in grid.Columns.OrderBy(c => c.DisplayIndex).ToList())
    {
      sb.Append("\"");
      sb.Append(column.Header.ToString().Replace("\"", "\"\""));
      sb.Append("\";");
    }
    sb.AppendLine();
  }

  foreach (object obj in grid.ItemsSource)
  {
    grid.ScrollIntoView(obj, grid.Columns.OrderBy(c => c.DisplayIndex).Last());

    foreach (DataGridColumn c in grid.Columns.OrderBy(c=>c.DisplayIndex).ToList())
    {
      sb.Append("\"");
      var el = c.GetCellContent(obj);
      if (el==null)
      {
        // load values by reflection
        string str = string.Empty;
        var propInfo = obj.GetType().GetProperty(c.Header.ToString());
        if (propInfo != null)
          str = propInfo.GetValue(obj, null).ToString();
        sb.Append(str.Replace("\"", "\"\""));
      }
      else if (el is TextBlock)
      {
        var tb = el as TextBlock;
        sb.Append(tb.Text.Replace("\"", "\"\""));
      }
      else if (el is CheckBox)
      {
        var cb = el as CheckBox;
        sb.Append(cb.IsChecked == true ? "True" : "False");
      }
      else
      {
        int i = 0;
      }
      sb.Append("\";");
    }
    sb.AppendLine();
  }

  return sb.ToString();
}

Debugging WCF

posted Feb 8, 2010, 11:26 AM by Rene Rasmussen   [ updated Feb 8, 2010, 1:26 PM ]

I have been using wcf in several projects and I love the possibilities provided by wcf to connect servers and clients simply by specifying the right setup in the config files. But debugging connections specified in wcf configurations doesn’t really follow the old school debugging scheme where we add a breakpoint and step into the source.
Some weeks ago I was working on a client server system (Eqatec Analytics) where the services have been running perfectly for several months. But suddenly we did notice a specific call failed when a large amount of data was requested. As I looked into the issue I found the server side seems to be running fine. I monitored the communication using firebug and the call consistently failed when the data received exceed ~1 MB. My first thought was the data size limits specified in the bindings, but they had more than enough space for sending my 1 MB of data – both on server side and on client side.
<system.serviceModel>
  ...
  <bindings>
    <basicHttpBinding>
      <binding name="ServicesBinding" maxReceivedMessageSize="3000000" 
               maxBufferSize="3000000">
        <readerQuotas maxArrayLength="3000000" maxStringContentLength="3000000"/>
      </binding>
    </basicHttpBinding>
  </bindings>
  <services>
  ...
  </services>
</system.serviceModel>

Then I decided I had to investigate the possibilities for debugging WCF configurations.
The first think to notice is the possibility to add trace listeners which would log errors and warnings to a file.
<configuration>
  <system.diagnostics>
    <trace autoflush="true" />
    <sources>
      <source name="System.ServiceModel.MessageLogging"
              switchValue="Information, Warning, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="myTracer" />
        </listeners>
      </source>
      <source name="System.ServiceModel"
              switchValue="Information, Warning, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="myTracer" />
        </listeners>
      </source>
      <source name="System.Runtime.Serialization">
        <listeners>
          <add name="myTracer" />
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="myTracer"
           type="System.Diagnostics.XmlWriterTraceListener"
           initializeData="c:\log\Traces.svclog" />
    </sharedListeners>
  </system.diagnostics>
</configuration>

After studying the log-files and further “goggling” I found the problem and it wasn’t actually related to the data size, but the number of data items to be serialized. The problem was solved with this setup
    <behaviors>
      <serviceBehaviors>
        <behavior name="Analytics.WCF.Services.StandardServiceBehavior">
         ...
          <dataContractSerializer maxItemsInObjectGraph="655360"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
So the problem was solved and everybody are happy, but the really lesson learned was how to debug this very strong tool we have in WCF.

I include a few links for more information on debugging WCF:

Can't find RiaContext

posted Jan 26, 2010, 11:00 AM by Rene Rasmussen

I have been testing the Business application template using RIA services and find it very interesting. I plan to post more on that subject later, especially how to use multiple tables with relations.

This is short entry is just a tip for others who get the November release of RIA services, but are testing older samples. You will probably realize your version don't know the RiaContext class.
With the renaming of .Net RIA services to WCF RIA Services the RiaContext has also been renamed and is now WebContext.

I simply replace all RiaContext with WebContext and all the older demo samples complied nicely, 
...well actually I also replaced all Context with DataContext, but then it worked. 

You will find more about upgrading from .Net RIA to WCF RIA in this blog.

Silverlight Button Background

posted Jan 16, 2010, 12:22 PM by Rene Rasmussen   [ updated Feb 1, 2010, 12:18 PM ]

Have you ever been to a restaurant ordering a red steak from the menu, just to find out that you very well done (almost white) steak?
  
Well, that is how I felt when I ordered a silverlight button with red background.

I created a background like this

and it looks like this
<Canvas Height="50" Width="200" Margin="0,0,0,20">
    <Canvas.Background>
      <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="#FFB72020" Offset="0.539"/>
        <GradientStop Color="#FFFFDCDC"/>
        <GradientStop Color="#FF530000" Offset="1"/>
      </LinearGradientBrush>
    </Canvas.Background>
</Canvas>

but when I create a button with the same background
<Button Height="50" Width="200" Click="Button2_Click" x:Name="_button2">
    <Button.Background>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="#FFB72020" Offset="0.539"/>
            <GradientStop Color="#FFFFDCDC"/>
            <GradientStop Color="#FF530000" Offset="1"/>
        </LinearGradientBrush>
    </Button.Background>
    <TextBlock>Click Me</TextBlock>
</Button>
it looked like this
That was not the button background I ordered!

So I started digging...
The default button template for in Silverlight is defined as 
<ControlTemplate TargetType="controls:Button">
    <Grid>
        <!-- snipped the 36 lines of VisualStatManager here -->
        <Border x:Name="Background" CornerRadius="3" Background="White" 
                BorderThickness="{TemplateBinding BorderThickness}" 
                BorderBrush="{TemplateBinding BorderBrush}">
            <Grid Background="{TemplateBinding Background}"  Margin="1">
                <Border Opacity="0"  x:Name="BackgroundAnimation" 
                        Background="#FF448DCA" />
                <Rectangle x:Name="BackgroundGradient" >
                    <Rectangle.Fill>
                        <LinearGradientBrush StartPoint=".7,0" EndPoint=".7,1">
                            <GradientStop Color="#FFFFFFFF" Offset="0" />
                            <GradientStop Color="#F9FFFFFF" Offset="0.375" />
                            <GradientStop Color="#E5FFFFFF" Offset="0.625" />
                            <GradientStop Color="#C6FFFFFF" Offset="1" />
                        </LinearGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
            </Grid>
        </Border>
        <ContentPresenter x:Name="contentPresenter" 
            Content="{TemplateBinding Content}" 
            ContentTemplate="{TemplateBinding ContentTemplate}"
            VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
            Margin="{TemplateBinding Padding}"/>
        <Rectangle x:Name="DisabledVisualElement" RadiusX="3" RadiusY="3" 
                   Fill="#FFFFFFFF" Opacity="0" IsHitTestVisible="false" />
        <Rectangle x:Name="FocusVisualElement" RadiusX="2" RadiusY="2" 
                   Margin="1" Stroke="#FF6DBDD1" StrokeThickness="1" 
                   Opacity="0" IsHitTestVisible="false" />
    </Grid>
</ControlTemplate>
...so, the standard button template is using a rectangle which hide background defined on the button.

I created I quick fix (hiding the rectangle), now the background shines through.
  public color SlBackgroundButton : Button
  {
    public override void OnApplyTemplate()
    {
      base.OnApplyTemplate();

      Rectangle rect = GetTemplateChild("BackgroundGradient") as Rectangle;
      if (rect != null)
      {
        LinearGradientBrush lbrush = rect.Fill as LinearGradientBrush;
        if (lbrush != null && lbrush.GradientStops.Count > 3)
        {
          lbrush.GradientStops[0].Color = Colors.Transparent;
          lbrush.GradientStops[1].Color = Colors.Transparent;
          lbrush.GradientStops[2].Color = Colors.Transparent;
          lbrush.GradientStops[3].Color = Colors.Transparent;
        }
      }
    }
  }

The result is the button "Steak" :-) I ordered


1-6 of 6