Expand/Collapse button in a Silverlight DataGrid
I am using a RowDetailsTemplate in a Silverlight DataGrid to show row details. Setting RowDetailsVisibilityMode="VisibleWhenSelected" does not give a good user experience (only one row can be expanded at a time, all rows cannot be collapsed). What's the easiest way to add an expand/collapse button on e开发者_高级运维ach row so that the rows can be expanded/collapsed independently?
I've been meaning to blog my solution to this. I set the grid RowDetailsVisibilityMode to Collapsed and use a DataGridTemplateColumn with a styled ToggleButton in it to toggle the row visibility.
The toggle button can be wired up to toggle the row visibility using either binding or through a TriggerAction.
Binding has to be done in code-behind since you are trying to bind ToggleButton.IsChecked to an element that is generated and does not exist in XAML (DataGridRow.DetailsVisibility)
(This will be allowed in SL5 with a stronger RelativeSource binding)
For both solutions I have this extension method in a helper class:
/// <summary>
/// Walk up the VisualTree, returning first parent object of the type supplied as type parameter
/// </summary>
public static T FindAncestor<T>(this DependencyObject obj) where T : DependencyObject
{
while (obj != null)
{
T o = obj as T;
if (o != null)
return o;
obj = VisualTreeHelper.GetParent(obj);
}
return null;
}
For code-behind binding method:
private void ToggleButton_Loaded(object sender, RoutedEventArgs e)
{
ToggleButton button = sender as ToggleButton;
DataGridRow row = button.FindAncestor<DataGridRow>(); //Custom Extension
row.SetBinding(DataGridRow.DetailsVisibilityProperty, new Binding()
{
Source = button,
Path = new PropertyPath("IsChecked"),
Converter = new VisibilityConverter(),
Mode = BindingMode.TwoWay
});
}
For TriggerAction method:
public class ExpandRowAction : TriggerAction<ToggleButton>
{
protected override void Invoke(object o)
{
var row = this.AssociatedObject.FindAncestor<DataGridRow>();
if (row != null)
{
if (this.AssociatedObject.IsChecked == true)
row.DetailsVisibility = Visibility.Visible;
else
row.DetailsVisibility = Visibility.Collapsed;
}
}
}
Then in XAML:
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ToggleButton Style="{StaticResource PlusMinusToggleButtonStyle}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<behaviors:ExpandRowAction/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ToggleButton>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
精彩评论