Xaml: Adding Visibility Behaviors Using Blend to A DataGrid for WPF or Silverlight
In Xaml the determining when to trigger the visibility, or the hiding of controls or their functionality is a key concept of doing either WPF or Silverlight programming. This article builds upon my article C#: WPF and Silverlight DataGrid Linq Binding Example Using Predefined Column Header Names in Xaml where we are going to add behaviors to the datagrid shown. (Don’t worry about reading the article, for I will get you up to speed with the code snippets in this article.) We will use Microsoft’s Expression Blend product to do the dirty work of xaml modification to our DataGrid and it will be shown in a step by step process.
Concept
In the previous article the idea was to load our datagrid with two columns of data. The first column showed us a filename and the second column displayed a modified filename with a count in it. We will take that one step further and have a description show up with the file size. Here is the resulting look:
The user gets the description when the row is clicked.
But what if we wanted to disable that functionality and automatically show the user all the items when the mouse hovers over the datagrid such as
Setup
First thing we need to do is setup our datagrid. Below is the xaml and the code behind to load our datagrid. Note the datagrid has the RowDetailsVisibiltyMode set to collapsed. That means that when a user clicks on the row, it will only select it and not open up our description. The loading of the ItemsSource happens during the construction and after the initial initialization and is shown in C# in the second pane.
<DataGrid x:Name="dgPrimary" RowDetailsVisibilityMode="Collapsed"> <DataGrid.RowDetailsTemplate> <DataTemplate> <TextBlock FontWeight="Bold" Text="{Binding Size, StringFormat=Size \{0\} (bytes)}" /> </DataTemplate> </DataGrid.RowDetailsTemplate> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Original}" Header="File Name Before" IsReadOnly="True" /> <DataGridTextColumn Binding="{Binding New}" Header="File Name After" IsReadOnly="True" /> </DataGrid.Columns> </DataGrid> |
dgPrimary.ItemsSource = new DirectoryInfo( "c:\\" ).GetFiles() .Select( ( fInfo, index ) => new { Original = fInfo.Name, New = string.Format( "{0}_{1}{2}", System.IO.Path.GetFileNameWithoutExtension( fInfo.Name ), index, System.IO.Path.GetExtension( fInfo.Name ) ), Size = fInfo.Length } ); |
Behaviors and Blend
One of the easiest ways to add a behavior [of the action] to a control is to use Blend to add an interaction behavior. In our case we want a mouse over action to open up all of the Row Details and a secondary action to close them when the mouse leaves. The behavior we need to search for in blend is the ChangePropertyAction. Below we drag (or add) two behaviors to the datagrid and change the RowDetailsVisibilityMode to visible on mouse enter and to collapsed on mouse leave.
![]() |
![]() |
Then when we build and run the app, the mouse hover over makes the descriptions visible and collapsed depending on the mouse. Here is the final xaml:
<DataGrid x:Name="dgPrimary" RowDetailsVisibilityMode="Collapsed"> <DataGrid.RowDetailsTemplate> <DataTemplate> <TextBlock FontWeight="Bold" Text="{Binding Size, StringFormat=Size \{0\} (bytes)}" /> </DataTemplate> </DataGrid.RowDetailsTemplate> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Original}" Header="File Name Before" IsReadOnly="True" /> <DataGridTextColumn Binding="{Binding New}" Header="File Name After" IsReadOnly="True" /> </DataGrid.Columns> <i:Interaction.Triggers> <i:EventTrigger EventName="MouseEnter" SourceObject="{Binding ElementName=dgPrimary}"> <ei:ChangePropertyAction x:Name="cpaEnter" PropertyName="RowDetailsVisibilityMode"> <ei:ChangePropertyAction.Value> <DataGridRowDetailsVisibilityMode>Visible</DataGridRowDetailsVisibilityMode> </ei:ChangePropertyAction.Value> </ei:ChangePropertyAction> </i:EventTrigger> <i:EventTrigger EventName="MouseLeave"> <ei:ChangePropertyAction x:Name="cpaLeave" PropertyName="RowDetailsVisibilityMode" /> </i:EventTrigger> </i:Interaction.Triggers>