WordPress database error: [INSERT, UPDATE command denied to user '51213-2'@'10.10.20.25' for table 'wp_options']
INSERT INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('_transient_doing_cron', '1715235309.3269159793853759765625', 'yes') ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)


Warning: Cannot modify header information - headers already sent by (output started at /home/lexiqued/www/WordPress/wp-includes/wp-db.php:1502) in /home/lexiqued/www/WordPress/wp-includes/feed-rss2.php on line 8
SL – Jonathan ANTOINE's thoughts http://www.jonathanantoine.com Yet another blog about... Sun, 19 Feb 2012 15:17:12 +0000 en-US hourly 1 https://wordpress.org/?v=5.5.3 How to bind an ItemsControl to an Enum with localized descriptions http://www.jonathanantoine.com/2011/11/22/how-to-bind-an-itemscontrol-to-an-enum-with-localized-descriptions/ http://www.jonathanantoine.com/2011/11/22/how-to-bind-an-itemscontrol-to-an-enum-with-localized-descriptions/#comments Tue, 22 Nov 2011 15:38:12 +0000 http://www.jonathanantoine.com/?p=835 Today, it’s a blog on a tip to use the values of an enum as the source of an ItemsControl (ListBox, ComboBox, ListView, etc.) and display them nicely using attributes.

We’ll provide a localized description to be displayed and the value will still be available to the binding.

In this post we’ll discover two very similar but differents solutions to this common issue.

[table-of-content]

Foundations

The foundation of the solution is based on reflection.
For a provided type, the RetrieveFromCacheOrAddIt method read the Display attributes and create a list of tuples from it. A cache is created so the reflection is done only once by type.

The first item (Item1) of the tuple is the real value and the second item (Item2) is the text to be displayed. If the attribute is not found, then the value of the enum is used as a description.

The display attribute can be found in the System.ComponentModel.DataAnnotations.dll assembly.

[csharp]
//The cache to use
private readonly Dictionary<Type, List<Tuple<Object, Object>>>
_cache = new Dictionary<Type, List<Tuple<Object, Object>>>();

//The method which fill the cache.
private object RetrieveFromCacheOrAddIt(Type type)
{
//if it is not already in cache
if (!this._cache.ContainsKey(type))
{
//get the fields of the type via reflection
var fields = type.GetFields().Where(field => field.IsLiteral);
var values = new List<Tuple<Object, Object>>();
foreach (var field in fields)
{
//retrieve the display attributes of the fields
var a = (DisplayAttribute[])field
.GetCustomAttributes(typeof(DisplayAttribute), false);
var valueOfField = field.GetValue(type);

//if there is a display attribute on the field.
if (a.Length > 0)
{
var newTuple1 =
new Tuple<Object, Object>(valueOfField, a[0].GetName());
values.Add(newTuple1);
}
//if not, use the value
else
{
var newTuple =
new Tuple<Object, Object>(valueOfField, valueOfField);
values.Add(newTuple);
}
}
this._cache[type] = values;
}

return this._cache[type];
}[/csharp]

Here is an example of an enum with the correct DisplayAttributes set:
[csharp] public enum MyEnum
{
[Display(Name = "My fist name to display")]
ValueOne,

[Display(Name = "My second name to display")]
ValueTwo,

[Display(Name = "My third name to display")]
ValueThird,

ValueFourWithNoDisplayAttribute
}[/csharp]

Use a converter

The first idea which comes in our WPF developer brain is to use a converter. This is easy to implement and pretty classic.

Here is the codeof the converter and the regarding XAML usage.
[csharp] public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
var type = value as Type;
return type == null ? null : RetrieveFromCacheOrAddIt(type);
}[/csharp]

The converter is defined in a resource scope available to the binding and the Type of the enum is provided by setting the Source property of the binding to the target enum type using the x:Type markup extension. Here is an example:
[xml]
<DockPanel Margin="10">
<DockPanel.Resources>
<local:EnumToDictionnaryConverter x:Key="EnumToDictionnaryConverter" />
</DockPanel.Resources>
<TextBlock DockPanel.Dock="Left" Text="First solution : " FontWeight="Bold" />
<ComboBox DisplayMemberPath="Item2" SelectedValuePath="Item1"
SelectedValue="{Binding MyPropertyOnTheViewModel}"
ItemsSource="{Binding Source={x:Type local:MyEnum},
Converter={StaticResource EnumToDictionnaryConverter}}" />
</DockPanel>[/xml]

Use a markup extension

The second idea, really less verbose, is to create a markup extension. The type of the enum will be provided as a parameter.

Here is the code of the extension and the XAML usage of it below.
[csharp] public class EnumToDictionnaryExtension : MarkupExtension
{
public Type TargetEnum { get; set; }
public EnumToDictionnaryExtension(Type type) { TargetEnum = type; }

public override object ProvideValue(IServiceProvider serviceProvider)
{
var type = TargetEnum;
if (type == null) return null;
return RetrieveFromCacheOrAddIt(type);
}

//RetrieveFromCacheOrAddIt snippet from above !
}[/csharp]

DisplayMemberPath and SelectedValuePath still need to be set but there is no converter to define and unusual binding source to use.
[xml]
<ComboBox DisplayMemberPath="Item2" SelectedValuePath="Item1"
ItemsSource="{local:EnumToDictionnary {x:Type local:MyEnum}}" />[/xml]

Localisation – i18n

If you want to localize the used text, you can provide the type of a resource file to use.
The Display attribute GetName method will automatically pull the value from the resource file with the ‘name’ key of the attribute.

For example if I change the previous enum to the definition below, I will have to create a resource file (Localized.resx) and add values for the keys ‘Value1’, ‘Value2’ and ‘Value3’.
[csharp]public enum MyEnum
{
[Display(Name = "Value1", ResourceType = typeof(Localized))]
ValueOne,

[Display(Name = "Value2", ResourceType = typeof(Localized))]
ValueTwo,

[Display(Name = "Value3", ResourceType = typeof(Localized))]
ValueThird,

}[/csharp]
Then I can also create an another resource file named Localized.fr-FR.resx and translate the description in french.

If I set the culture of the UI thread to french, the values will be translated in it. Tada !
[csharp]Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");[/csharp]

Demo

I created a little demo which you can find in my DropBox folder. It presents the two solutions. As you can see in the screenshot below, if no display attribute is set, the value of the enum is used:

[/table-of-content]

]]>
http://www.jonathanantoine.com/2011/11/22/how-to-bind-an-itemscontrol-to-an-enum-with-localized-descriptions/feed/ 6
Coded UI tests : my TextBlock is not found, how to find it ? http://www.jonathanantoine.com/2011/11/09/coded-ui-tests-my-textblock-is-not-found-how-to-find-it/ http://www.jonathanantoine.com/2011/11/09/coded-ui-tests-my-textblock-is-not-found-how-to-find-it/#comments Wed, 09 Nov 2011 16:16:59 +0000 http://www.jonathanantoine.com/?p=806 In the previous post, we have seen that setting the AutomationId can greatly help us when we want to perform some UI Tests.

Todyay, I struggled with a problem which seems common after some digging on the net : the TextBlock control is not found and no assertion can be set on it.
But it does not always occur and it is then difficult to debug this strange behavior.

In this post we’ll see why this happen and how to solve this issue.

Why and When ?

The problem comes from the TextBlockAutomationPeer. If you digg into its code you can find this :
[csharp]override protected bool IsControlElementCore()
{
return ((TextBlock)Owner).TemplatedParent == null;
} [/csharp]

This basically means that if the TextBlock is inside a template, any kind of template, it is not exposed.
For example, if in an ItemsControl, a Listbox or another control, you use a DataTemplate containing a TextBlock, this one won’t be find by the automation client. Here is a code example :
[xml]<Grid>
<Grid.Resources>
<DataTemplate x:Key="ItemTemplate">
<TextBlock Text="{Binding }" />
</DataTemplate>
</Grid.Resources>
<ListBox ItemsSource="{Binding }"
ItemTemplate="{StaticResource ItemTemplate}" />
</Grid>[/xml]

A solution

The only dirty solution I find is to create your own TextBlock control with its own corrected AutomationPeer.
It will be based on the original TextBlockAutomationPeer but the IsControlElementCore method will always return true.
As a bonus, I let commented a snippet which will expose the TextBlock only if an AutomationId is set on it.

The code to write is really light. The real issue is that you have to update every TextBlock usage in the XAML of your application.
[csharp]
public class AutomatisableTextBlock : TextBlock
{
protected override AutomationPeer OnCreateAutomationPeer()
{
return new AlwaysVisibleTextBlockAutomationPeer(this);
}
}

//The corrected AutomationPeer is based on the TextBlockAutomationPeer
public class AlwaysVisibleTextBlockAutomationPeer : TextBlockAutomationPeer
{
public AlwaysVisibleTextBlockAutomationPeer(TextBlock t)
: base(t) { }

protected override bool IsControlElementCore()
{
//if (String.IsNullOrEmpty(GetAutomationId()))
// return false;
return true;
}
}
[/csharp]

Finally, the demo app XAML needs to be updated:
[xml]
<Grid>
<Grid.Resources>
<DataTemplate x:Key="ItemTemplate">
<local:AutomatisableTextBlock Text="{Binding }" />
</DataTemplate>
</Grid.Resources>
<ListBox ItemsSource="{Binding }"
ItemTemplate="{StaticResource ItemTemplate}" />
</Grid>[/xml]

After the update, the TextBlock is correctly found by any automation client:

]]>
http://www.jonathanantoine.com/2011/11/09/coded-ui-tests-my-textblock-is-not-found-how-to-find-it/feed/ 4
Coded UI tests : AutomationId or how to find the chose one (control) ! http://www.jonathanantoine.com/2011/11/03/coded-ui-tests-automationid-or-how-to-find-the-chose-one-control/ http://www.jonathanantoine.com/2011/11/03/coded-ui-tests-automationid-or-how-to-find-the-chose-one-control/#comments Thu, 03 Nov 2011 16:07:10 +0000 http://www.jonathanantoine.com/?p=737 In my previous post on Coded UI tests, we have seen how to make a control discoverable by a Microsoft UI Automation client including the Coded UI tests builder.

This is a first step and the controls now need to be uniquely identified. This is done via the AutomationId property. In this post we’ll digg a little more in coded UI tests and discover the AutomationId property.
[table-of-content]

AutomationId : what is it ?

As stated in the previous post, an application exposes AutomationPeer. They are then found by UI Automation Client as AutomationElement objects. These items are identified uniquely by the AutomationId property.

This identifier is not mandatory but it’s a best practice to set it when you plan to perform UI tests.

To retrieve a control, the automation peer tree is used : first the top element is found, then the automation client iterate on its children, then the children of the children until it finds the aimed element. Each of the children and the final target is find using conditions and usually, one is set on the automation id.

The automation id is a property which helps you to find a specific UI element among others. This is, for example, very useful when you want to find a specific item in a collection (listbox, menus, etc.). Another benefit is that, as the control is uniquely identified, you can move it elsewhere or change its name and it will still be found by a previous code needing it.

To leverage the power of it, there is a rule to respect: it’s expected to be the same in any instance of the same application and ‘unique by instance in its scope‘.

  1. If you exit the application and launch it again, the value will not change.
  2. If you change the culture of the PC/Application, it will not change.
  3. If you launch several instance of the application, it remains the same on each of them.
  4. If there is several usage of the control in the application, each of them has a different automation id on each scope. A scope is defined by the path in the tree to go to the element. For example each menu item of a menu can be named in a generic way : menuItem1, menuItem2, etc.

This is a rule and you are not forced by the runtime or anything to follow it. As a proof, AutomationPeer returns a default value of string.empty which is really not unique!

By the way, if you want to set a name to a control(for example to improve accesibility) uses the Name property instead of the AutomationId one.

How to set it ?

The AutomationPeer exposes a method GetAutomationId of type string. When you create a custom AutomationPeer, you can override the GetAutomationIdCore abstract method to return a custom value. The default value is string.empty.

You can also set the returned value via XAML using the AutomationProperties’s AutomationId attached property.
[xml]<MyControl AutomationProperties.AutomationId="AnUniqueValue"/>[/xml]

The default implementation (which you can override) of the the AutomationPeer’s GetAutomationIdCore method read the value from the attached property too:
[csharp]
//In the AutomationPeer class.
protected override string GetAutomationIdCore()
{
return (AutomationProperties.GetAutomationId(_owner));
}[/csharp]

How to use it in automation clients ?

This is pretty straightforward, you just have to define a condition on it, providing the searched value:
[csharp]string seekedAutomationId = "AnUniqueValue";

//Create the condition
var condition = new PropertyCondition(
AutomationElement.AutomationIdProperty, seekedAutomationId);

//Retrieve the element via FindFirst(best practice)
var elt = AutomationElement.RootElement.FindFirst(TreeScope.Descendants, condition);
[/csharp]

Also, you can retrieve the AutomationId value of an element using this code:
[csharp]AutomationElement autoElement = //Retrieves the auto element here.
string autoId =
autoElement.GetCurrentPropertyValue(AutomationElement.AutomationIdProperty)
as string;[/csharp]

How is it used by the Coded UI tests builder ?

This tool is the one shipped with Visual Studio with which you can record coded UI tests.

If no AutomationId is set, the tools generates code which search the button based on its properties’ values. As you can see, if you move the button elsewhere, the test won’t be able to find it again.
[csharp]var mUIYoupiButton1 = new WpfButton(this);
#region Search Criteria
mUIYoupiButton1.SearchProperties[WpfButton.PropertyNames.Name] = "Youpi !";
mUIYoupiButton1.SearchProperties[WpfButton.PropertyNames.Instance] = "2";
mUIYoupiButton1.WindowTitles.Add("MainWindow");
#endregion

return mUIYoupiButton1;
[/csharp]

When you set the automation id, the generated code is smart enough to use it to identify the button:
[csharp]var mUIYoupiButton = new WpfButton(this);
#region Search Criteria
mUIYoupiButton
.SearchProperties[WpfButton.PropertyNames.AutomationId] = "AnUniqueValue";
mUIYoupiButton.WindowTitles.Add("MainWindow");
#endregion

return mUIYoupiButton;[/csharp]

How to find it on existing application ?

Snoop for a WPF application, UI Spy for a Silverlight one !

As this is a standard property you can read it as any other with these tools! In using it, don’t forget that it’s not an inherited property and that you have to select precisely the control (It can be difficult using the Ctrl+Shift shortcut).
AutomationId retrieval with snoop

When to set the AutomationId ?

As you’ve read, this is not mandatory to set it but it is a best practice.

My opinion is to do it right when you code in any application which may be tested trough coded UI tests.

To set it on all control is useless because not all control will be tested. Instead, I recommend to identify the key controls of the application. Usually, it’s button, menu items, any controls which can receive input from the users (keyboard and/or mouse).
Also, don’t forget the controls which evolve on user interaction and display results / information.

It can be a good thing, before to start to write any code, to set up a meeting with the quality team, deciding what are those controls. The member of the quality team usually know what they test 🙂

AutomationId and ItemsControl or dynamically generated controls.

In any user interface, there is dynamic parts. One of the most common are ItemsControls. A recurrent question is “how can I define an AutomationId on something which is dynamic ?“.

My answer is : “as you would do for any other problem – via a binding“. The AutomationId is an attached dependency property and you can set a binding on it which will solve your problem.

Let’s say, that I want to display a list of person, then in the DataTemplate representing a person, I can use the Id property of the person as an Automation id. Here is an example:
[xml]<DataTemplate x:Key="PersonDataTemplate" DataType="model:Person">
<TextBlock Text="{Binding Name}">
<AutomationProperties.AutomationId>
<MultiBinding StringFormat="AID_{0}-{1}">
<Binding Path="Name" />
<Binding Path="Id" />
</MultiBinding >
</AutomationProperties.AutomationId>
</TextBlock>
</DataTemplate>

<ItemsControl x:Name="_myItemsControl"
ItemTemplate="{StaticResource PersonDataTemplate}" />

[/xml]

The real issue is to respect the previously mentioned rule: “how to keep the id unique and the same in all the instance of the application”. The solution will depends of the application and the goal of the control.

If the aimed control is targeted because of the value it represents (a specific person) then you can generate the id using the model property (the id of the person).

If the aimed control is targeted because of its position in the interface (the 5th item in the list) then you can bind to UI-related properties like the alternation count for example. You can also find a technique which uses the index of the item in the list as an AutomationId.

I am sad to tell it but there is no solution which will work in all case 🙁

More to read on the subject

If you want to discover more on this subject, here is some interesting links:

  1. Visual Studio Team Test blog posts on the subject : part 1 and part 2.
  2. UI Automation Properties Overview on MSDN.
  3. Use the AutomationID Property on MSDN.
  4. WPF Application Quality Guidelines on UI testing.
  5. My previous post on the subject explaining Automation peers.

[/table-of-content]

]]>
http://www.jonathanantoine.com/2011/11/03/coded-ui-tests-automationid-or-how-to-find-the-chose-one-control/feed/ 13
MVVM : De la découverte à la maîtrise – my book is out ! http://www.jonathanantoine.com/2011/09/29/mvvm-de-la-decouverte-a-la-maitrise-my-book-is-out/ http://www.jonathanantoine.com/2011/09/29/mvvm-de-la-decouverte-a-la-maitrise-my-book-is-out/#comments Wed, 28 Sep 2011 23:30:35 +0000 http://www.jonathanantoine.com/?p=594 MVVM is the pattern to know when building WPF, Silverlight, Windows phone and even WinRT (for what I know!) application.

There is already some good books in english which can help the developers to discover and understand it but there were none in French.

This is no more the case because my friend Thomas Lebrun (blog, twitter) and I wrote one entitled “MVVM De la découverte à la maîtrise”.

You can buy it at different places:

  1. A numeric version can be found on our editor page
  2. It is available on Amazon too
  3. The french store, “FNAC” is selling it too !
  4. A printed version can be ordered on lulu

Here is the different things we have covered in it:

  • Présentation du pattern MVVM
  • Les différents éléments et leurs rôles
  • Les différentes philosophies (view-first, model-first, view-model first)
  • Construire la partie modèle
  • Construire un ViewModel
  • Construire les vues
  • Edition de contrôles personnalisés
  • MVVM et Testabilité
  • Glossaire

Feel free to share this post 🙂

An updated, working, version of the source code is available at this adress : http://db.tt/XQfstVbB

Regards,

]]>
http://www.jonathanantoine.com/2011/09/29/mvvm-de-la-decouverte-a-la-maitrise-my-book-is-out/feed/ 11
UPDATE: WPF 4.5’s MarkupExtension : Invoke a method on the ViewModel / DataContext when an event is raised. http://www.jonathanantoine.com/2011/09/23/wpf-4-5s-markupextension-invoke-a-method-on-the-viewmodel-datacontext-when-an-event-is-raised/ http://www.jonathanantoine.com/2011/09/23/wpf-4-5s-markupextension-invoke-a-method-on-the-viewmodel-datacontext-when-an-event-is-raised/#comments Fri, 23 Sep 2011 09:29:24 +0000 http://www.jonathanantoine.com/?p=461 We have seen in a previous post that WPF 4.5 enable the use of custom markup extensions to provide event handlers.

In this post we’ll see that we can execute a method on the DataContext of the control when an event is raised using this new ability of the MarkupExtension.

With some tiny modifications you can run it on Silverlight too !

How does it work ?

For a start, I suggest you to read my first post describing “markup extensions for events in WPF 4.5”.
The code used is based on the one presented in this previous post.

As already said, the DataContext may not be available when the MarkupExtension is used so it is not possible to register directly a Delegate on the ViewModel because we do not have it.

So the tip I use is to create a proxy handler on the markup extension itself. When this handler is called, I will retrieve the viewModel from the DataContext because it will then be set. From it I am able to get the targeted method trough reflection. Then I just have to execute the method if it truly exists.

The name of the method to call is passed in the constructor of the extension and is exposed as a property named ActionName.

The code !

It also can be found on my dropbox folder after registration.
[csharp]
public class Call : MarkupExtension
{
public string ActionName { get; set; }
public Call(string actionName){ ActionName = actionName; }

public override object ProvideValue(IServiceProvider serviceProvider)
{
IProvideValueTarget targetProvider = serviceProvider
.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
if (targetProvider == null)
throw new InvalidOperationException(@"The CallAction extension
can’t retrieved the IProvideValueTarget service.");

targetProvider.TargetObject as FrameworkElement;
if (target == null)
throw new InvalidOperationException(@"The CallAction extension
can only be used on a FrameworkElement.");

var targetEventAddMethod = targetProvider.TargetProperty as MethodInfo;
if (targetEventAddMethod == null)
throw new InvalidOperationException(@"The CallAction extension
can only be used on a event.");

//Retrieve the handler of the event
ParameterInfo[] pars = targetEventAddMethod.GetParameters();
Type delegateType = pars[1].ParameterType;

//Retrieves the method info of the proxy handler
MethodInfo methodInfo = this.GetType().GetMethod("MyProxyHandler",
BindingFlags.NonPublic | BindingFlags.Instance);

//Create a delegate to the proxy handler on the markupExtension
Delegate returnedDelegate =
Delegate.CreateDelegate(delegateType, this, methodInfo);

return returnedDelegate;

}

void MyProxyHandler(object sender, EventArgs e)
{
FrameworkElement target = sender as FrameworkElement;
if (target == null) return;
var dataContext = target.DataContext;
if (dataContext == null) return;

//get the method on the datacontext from its name
MethodInfo methodInfo = dataContext.GetType()
.GetMethod(ActionName, BindingFlags.Public | BindingFlags.Instance);
methodInfo.Invoke(dataContext, null);
}
}
[/csharp]

How to use it ?

Use it is simplier thant to create it ! You simply have to use the markupExtension as you would declare a Binding in the XAML:
[xml]<Grid PreviewMouseDown="{custMarkup:Call MyMethodToCallOnTheViewModel}"
Background="Transparent"/>[/xml]

For the record, here is the method I created on my ViewModel :
[csharp]public void MyMethodToCallOnTheViewModel()
{
MessageBox.Show("oh no, you’ve got me …");
}
[/csharp]

This example leads to really funny things 🙂 :

Update !

As pointed out by ThomasX in a comment below, the returned target property is not always a MethodInfo but can be an EventInfo.
It seems to be a bug in this release (a connection is open for it) and I am pretty sure it will be corrected in the final release. By the time, I updated the code to work in all case. Here are only the revelant two parts.

First we check the type of the target property:
[csharp]Delegate returnedDelegate =null;

var targetEventAddMethod = targetProvider.TargetProperty as MethodInfo;
if (targetEventAddMethod != null)
returnedDelegate= CreateDelegateForMethodInfo(targetEventAddMethod);

var targetEventInfo = targetProvider.TargetProperty as EventInfo;
if (targetEventInfo != null)
returnedDelegate=CreateDelegateForEventInfo(targetEventInfo);[/csharp]

Then, here is the method to create a delegate in case the target property is of EventInfo type:
[csharp] private Delegate CreateDelegateForEventInfo(EventInfo targetEventInfo)
{

if (targetEventInfo == null)
throw new InvalidOperationException(
@"The CallAction extension can only be used on a event.");

Type delegateType = targetEventInfo.EventHandlerType;

//Retrieves the method info of the proxy handler
MethodInfo methodInfo = this.GetType().GetMethod("MyProxyHandler",
BindingFlags.NonPublic | BindingFlags.Instance);

//Create a delegate to the proxy handler on the markupExtension
Delegate returnedDelegate =
Delegate.CreateDelegate(delegateType, this, methodInfo);
return returnedDelegate;
}[/csharp]

How can it be improved ?

Here is the improvement I lacked the time to implement:

  • Check if the method on the ViewModel has the correct signature,
  • Pass the event’s arguments to the ViewModel method if it accepts it,
  • Cache the reflected method to save execution time,

As said in my previous post, I think that because of the Blend integration, the preferred way to do this kind of feature has to be the behavior/triggers.

]]>
http://www.jonathanantoine.com/2011/09/23/wpf-4-5s-markupextension-invoke-a-method-on-the-viewmodel-datacontext-when-an-event-is-raised/feed/ 8