By admin
Tags: wpf,datagrid,sort,tri
Ce billet, http://blogs.msdn.com/jgoldb/archive/2008/08/26/improving-microsoft-datagrid-ctp-sorting-performance.aspx, nous explique comment obtenir de meilleures performances lors du tri de la WPF DataGrid.
Voici une variante qui vous permettra de trier une datagrid liée à un XmlDataProvider.
1: public class XmlDataGridComparer<T> : IComparer where T : IComparable
2: { 3: private readonly ListSortDirection m_sortDirection;
4: private readonly string m_sortMemberPath;
5:
6: public XmlDataGridComparer(DataGridColumn column)
7: { 8: m_sortMemberPath = column.GetSortMemberPath();
9: m_sortDirection = column.ToggleSortDirection();
10: }
11:
12: public int Compare(object x, object y)
13: { 14: XmlElement a = (XmlElement)x;
15: XmlElement b = (XmlElement)y;
16:
17: if (a == null || b == null)
18: { 19: throw new ArgumentException();
20: }
21:
22: T da = GetObject(a);
23: T db = GetObject(b);
24:
25: if (m_sortDirection == ListSortDirection.Ascending)
26: { 27: return da.CompareTo(db);
28: }
29: else
30: { 31: return db.CompareTo(da);
32: }
33: }
34:
35: private T GetObject(XmlElement element)
36: { 37: string value = element.GetElementsByTagName(m_sortMemberPath).Item(0).InnerXml;
38: return (T)Convert.ChangeType(value, typeof(T));
39: }
40: }
Ce code utilise deux méthodes d'extension sur les DataGridColumn que voici:
1: public static class DataGridColumnExtension
2: { 3: /// <summary>
4: /// Gets the sort member path.
5: /// </summary>
6: /// <param name="column">The sorted column.</param>
7: /// <returns>The sort member path.</returns>
8: public static string GetSortMemberPath(this DataGridColumn column)
9: { 10: string sortPropertyName = column.SortMemberPath;
11: if (string.IsNullOrEmpty(sortPropertyName))
12: { 13: DataGridBoundColumn boundColumn = column as DataGridBoundColumn;
14: if (boundColumn != null)
15: { 16: Binding binding = boundColumn.DataFieldBinding as Binding;
17: if (binding != null)
18: { 19: if (!string.IsNullOrEmpty(binding.XPath))
20: { 21: sortPropertyName = binding.XPath;
22: }
23: else if (binding.Path != null)
24: { 25: sortPropertyName = binding.Path.Path;
26: }
27: }
28: }
29: }
30:
31: return sortPropertyName;
32: }
33:
34: /// <summary>
35: /// Toggles the sort direction.
36: /// </summary>
37: /// <param name="column">The sorted column.</param>
38: /// <returns>
39: /// <see cref="ListSortDirection.Ascending"/> or <see cref="ListSortDirection.Descending"/>
40: /// depending of the previous sort direction.
41: /// </returns>
42: public static ListSortDirection ToggleSortDirection(this DataGridColumn column)
43: { 44: ListSortDirection sortDirection = ListSortDirection.Ascending;
45: ListSortDirection? currentSortDirection = column.SortDirection;
46:
47: if (currentSortDirection.HasValue && currentSortDirection.Value == ListSortDirection.Ascending)
48: { 49: sortDirection = ListSortDirection.Descending;
50: }
51:
52: column.SortDirection = sortDirection;
53:
54: return sortDirection;
55: }
56: }
Il ne reste plus qu'à instancier la class XmlDataGridComparer avec le type d'object contenu dans notre colonne dans l'événement Sorting de la DataGrid :
1: ListCollectionView lcv = (ListCollectionView)CollectionViewSource.GetDefaultView(dataGrid.ItemsSource);
2: lcv.CustomSort = new XmlDataGridComparer<string>(e.Column)
Et voilà...
Lorsque l'on utilise le SCSF/CAB, il arrive parfois que l'on se retrouve confronté à des exceptions quelques peux obscure du genre 'One or more exceptions occurred while firing the topic ....' .
Ces exceptions sont levées lorsqu'une fonction appellée dans un Event CAB à un problème.
Pour avoir plus d'informations lors du debugging, on peux simplement examiner la propriété Exceptions qui contient un tableau des exceptions levée lors de l'appele à l'événement. Mais comment faire lorsque l'application n'est plus sous contrôle du développeur et que le log vous renvoie uniquement ce magnifique message 'One or more blah blah...' ??
Eh bien en utilisant la classe EventTopicExceptionFormatter qui nous est créée automatiquement par SCSF dans Infrastructure.Library. Il suffit ensuite de configurer un nouveau type d'exception dans EntLib:
<exceptionHandling>
<exceptionPolicies>
<add name="Default Policy">
<exceptionTypes>
<add type="Microsoft.Practices.CompositeUI.EventBroker.EventTopicException, Microsoft.Practices.CompositeUI, Version=1.0.51205.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
postHandlingAction="NotifyRethrow" name="EventTopicException">
<exceptionHandlers>
<add logCategory="General" eventId="100" severity="Error" title="GMS Exception Handling"
formatterType="YourNamespace.Infrastructure.Library.EntLib.EventTopicExceptionFormatter, Infrastructure.Library"
priority="0" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
name="Logging Handler" />
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
</exceptionPolicies>
</exceptionHandling>
Et voilà! Maintenant vos logs contiennent toutes les exceptions levées lors de votre event.
Un très bon article de John Papa à découvrir dans le numéro d'octobre du MSDN Magazine.
In this article I focus on using CTEs to address common development scenarios.
- describing how CTEs work
- scenarios they can be used to address
- advantages of using CTEs versus using traditional T-SQL constructs, such as derived tables, views, and custom procedures
- several examples
- how and where they can be used (where not to)
- how CTEs handle recursive logic
- define how a recursive CTE operates
Designing SQL Server's Common Table Expressions (CTE's) - John Papa [MVP C#]
By admin
Tags: wpf,tooltip
Lorsque l'on affiche un ToolTip dans un ItemControl avec un binding de donnée il arrive parfois que l'un des items ne doive pas afficher son ToolTip, par exemple si le text à afficher est vide.
Pour celà, il suffit de créer un Trigger sur le control qui "affiche" le tooltip.
<TextBlock Text="{Binding Path=Alias}" VerticalAlignment="Center" >
<TextBlock.ToolTip>
<TextBlock Text="{Binding Path=Description}" />
</TextBlock.ToolTip>
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding Description}"
Value="">
<Setter Property="ToolTipService.IsEnabled"
Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
Lorsqu'on utilise on ContextMenu dans un TreeView, il est normal de vouloir récupérer l'objet lié au noeud en cours.
Par exemple si nous avons le TreeView suivant en XAML:
<TreeView x:Name="myTreeView">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate
ItemsSource="{Binding Path=path}">
<TextBlock x:Name="node"
Text="{Binding Path=Text}"
>
<TextBlock.ContextMenu>
<ContextMenu>
<MenuItem Header="_Click Me"
Click="ctxClickMe_OnClick"/>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Pour cela, il existe plusieurs solutions. En voilà deux:
La première consiste à ajouter une référence sur l'objet binder à l'aide de la propriété Tag.
<MenuItem Header="_Click Me"
Click="ctxClickMe_OnClick"
Tag="{TemplateBinding Content}"/>
Dans le code behind on écrira l'event handler suivant:
protected void ctxClickMe_OnClick(object sender,
RoutedEventArgs e)
{
MenuItem menuItem = sender as MenuItem;
Foo foo = menuItem.Tag as Foo;
MessageBox.Show(foo.Id.ToString());
}
Malheureusement, cette méthode nous force à référencer l'objet lié sur tous les MenuItem.
La seconde solution nous évite cela en modifiant l'event handler de la faà§on suivant:
protected void ctxClickMe_OnClick(object sender,
RoutedEventArgs e)
{
MenuItem menuItem = (MenuItem)sender;
ContextMenu menu = (ContextMenu)menuItem.Parent;
TextBlock block = (TextBlock)menu.PlacementTarget;
Foo foo = block.DataContext as Foo;
MessageBox.Show(foo.Id.ToString());
}
En fait on remonte la hierarchie du MenuItem jusqu'à l'objet qui contient notre ContextMenu, ici un TextBlock, et on récupère le DataContext de cet objet.
Un très bon article qui décrit comment customizer les contrôles WPF.
Les modèles de contenus et les Templates des contrôles
By admin
Tags: wpf,tooltip
Pour ceux qui comme moi cherchent à créer un Tooltip avec des bords arrondis:
thewpfblog.com/
.. et encore mieux mais en portugais :-((
Tooltips personalizadas com WPF par Bruno Sonnino