Yet another blog about WPF, Surface, SL, MVVM, NUI....

2011

2010

2009

2008

Tag - Silverlight

Entries feed - Comments feed

 

UIAutomation, Coded UI tests, AutomationPeer and WPF/silverlight custom controls

24 March 2011

The Coded UI Tests, available in Visual Studio Ultimate or Premium, enable the creation of automated tests for the User Interface. This is a really nice feature because you are no more forced to make "hand made" tests which takes hours to be performed. 

The WPF controls in the framework are ready to be used by the Microsoft UI Automation which is itself used by the coded UI tests. This means that when you use the screen recorder to record the tests on your UI, it will be able to find the several control used in your application.

When you create you own custom controls or extend standard one, the recorder would not be able to find them at first and so a whole part of the screen may not be available for tests. Actually, it is possible to record a test but every steps will be done using screen position: click at (120,30), drag from (120,30) to (10,40). This is really annoying because any changes in the UI may broke all your tests.


In this post, we will see how to make a custom control fully useable in Coded UI tests scenarii. We will so answer the question "Why cannot the code UI test recorder find anything inside my WPF or Silverlight custom control ?"


Note: the same technique is used by the accessibility clients and by enabling this feature you also ease the people using your application through UI automation client like the partially-sighted person.

Continue reading...

 

[RIA Services] Why the client extended entities won't use the default backing store value ? EDITED

19 November 2010

The title may not be clear but I am talking about the entities that you extends on the client side using the fact that they are partial class. You may think as I was that if you add properties in them with backing store field, the properties will get initialed nicely : this is not the case and the property will always use the default value for the property type.

 

In this post we’ll discover how to perform our goal : create a property with the correct default value.

 

Take for example a Task entity in which you want to add a property IsVisible to tells the View if it should display it or not. By default, the Task should be visible. You will end up with this resulting code :

public partial class Task
{
//Default framework value for boolean is Falsek
private bool _isVisible = true;
public bool IsVisible
{
get
{
return _isVisible;
}
set
{
_isVisible = value;
}
}
}

 

But it won’t work and every loaded entity will have the IsVisible property to the default value which is Fase. Notice that I used the “loaded” verb and not “create” because the entity created use the correct value.

 

So why is it not working ?

In fact this is quite easy : when you load the entities, they are not created the usual way but de-serialized from the stream sended by the server so since the property is only on the client side, it wont be initialized with your value but with the default one. When you create entities, like the whole object is present on the client side and no de-serialisation is done, it will work as usual.

 

But RIA Services do not let us alone, the best practice is to initialize the default value of this kind in an override of the OnLoaded method. The final and working code should then be(take care to read the edit below after):

public partial class Task
{
protected override void OnLoaded(bool isInitialLoad)
{
base.OnLoaded(isInitialLoad);
IsVisible = true;
}
//Default framework value for boolean is Falsek
private bool _isVisible = true;
public bool IsVisible
{
get
{
return _isVisible;
}
set
{
_isVisible = value;
}
}
}

 

Hope this will save you the time to investigate I spend on this…

 

EDIT: In fact the entities are reloaded each time you submit changes and there is currently a bug (which will be fixed in the SP1  - as pointed out by Jeff in the comments) which will reset the value of your property to the default value even if it has been changed since.. But I have found a quite easy work around, by using two differents variables and knowing that RIA will simply ignore internal properties :

public partial class Task
{
protected override void OnLoaded(bool isInitialLoad)
{
base.OnLoaded(isInitialLoad);
//only for the initial load
if (isInitialLoad)
{
IsVisibleFix = true;
}
}
//Default framework value for boolean is Falsek
private bool _isVisible = true;
public bool _isVisible
{
//NO setter so RIA can't update the value
get { return _isVisible; }
}
//Internal so RIA ignore it and don't set the value
internal bool IsVisibleFix {
set { _isVisible = value; RaisePropertyChanged("DeleteVisibility"); }
}
}

 

You can read more on this forum post too : http://forums.silverlight.net/forums/t/203750.aspx

 

 

Shout itkick it on DotNetKicks.com

 

Migrate the Jetpack theme from Silverlight to WPF

14 October 2010

There is a great theme named Jetpack available for Silverlight applications which can be found on the Tim Heuer web site. I was wondering if it can be used in WPF applications and the answer is yes ! Here are the modifications I had to do to make all this work :

 

  • SelectionBackground replace by SelectionBrush (except for the DatePicker)
  • I removed the HyperlinkButton which does not exist in WPF
    DataGridFrozenGrid is not existing in WPF : I replaced it by a GRID
  • No navigation system : Frame style removed,
  • No page : replaced by HeaderedContentControl
  • DescriptionViewer : not available in WPF and removed,
  • TabNavigation replaced by : KeyboardNavigation.ControlTabNavigation
  • ValidationSummary does not exist in WPF : I removed it,
  • No Watermark in WPF: I removed it
  • ContentPresenter does not support direct content :  Ireplaced it by ContentControl,
  • AutoCompleteBox : not available in WPF and removed,
  • DataPager : not available in WPF and removed,
  • ChildWindow : not available in WPF and removed,
  • I removed the style targeting the textblock because it was imposing itself anywhere especially in the listboxitem leadind to wong behaviours,
  • I replace the differents name by their WPF PART_XXX counterparts
  • PasswordBox :  Ireplaced the ContentElement border by a ScrollViews named PART_ContentHost
  • I Replaced the animations key <DiscreteObjectKeyFrame KeyTime="0" Value=”Visible" /> by <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
  • Rewrite entirely the scrollbar style so it works nicely...
  • Rewrite entirely the Slider style so it works nicely...
  • Rewrite a fex the TabItem/Tab control style so it works nicely...

 

 

JetpackingWPF

 

So far, here is a list of the translated control’s theming :

  • TextBox,
  • ListBox,
  • Combobox,
  • PasswordBox,
  • ProgressBar,
  • Button,
  • ToggleButton,
  • RadioButton
  • Checkbox,
  • Scrollbar,
  • ScrollViewer,
  • Slider,
  • TreeView,
  • TabControl,
  • Label

 

So far, here is a list of the NOT TESTED and may not working element

  • Datagrid,
  • DatePicker,
  • Grid Splitter,
  • Expander,
  • ContextMenu.

 

 

PS: the demo application is in the post attachment…

 

I am currently working on it to add more working them components.

 

Edit (16/10/2010, 01:28) : I added new controls themes(Scrollbar, ScrollViewer, Slider, TreeView, TabControl, Label) and a new demo applications.


 Shout it kick it on DotNetKicks.com