Question

I'm trying to create a style which will make all my DataGrids select row -1 when they lose focus. I'm doing:

<Style TargetType="{x:Type DataGrid}">
    <Style.Triggers>
        <EventTrigger RoutedEvent="DataGrid.LostFocus">
            <BeginStoryboard>
                <Storyboard>
                    <Int32AnimationUsingKeyFrames Storyboard.TargetProperty="(DataGrid.SelectedIndex)">
                        <DiscreteInt32KeyFrame KeyTime="00:00:00" Value="-1" />
                    </Int32AnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Style.Triggers>
</Style>

It works only for the first time the focus is lost, but on the second time program crashes because of type conversion ecxeption. Is it possible without code behind?

Was it helpful?

Solution

According to my researches, attached behavior is the only acceptable solution for me. Hope this will help somebody more:

public class DataGridBehavior
{
    public static readonly DependencyProperty IsDeselectOnLostFocusProperty =
    DependencyProperty.RegisterAttached("IsDeselectOnLostFocus", typeof(bool), typeof(DataGridBehavior), new UIPropertyMetadata(false, PropertyChangedCallback));

    private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        var dg = dependencyObject as DataGrid;
        if (dg == null)
            return;

        if (e.NewValue is bool == false)
            return;

        if ((bool)e.NewValue)
            dg.LostFocus += dg_LostFocus;
    }

    static void dg_LostFocus(object sender, RoutedEventArgs e)
    {
        (sender as DataGrid).SelectedIndex = -1;
    }

    public static bool GetIsDeselectOnLostFocus(DataGrid dg)
    {
        return(bool)dg.GetValue(IsDeselectOnLostFocusProperty);
    }

    public static void SetIsDeselectOnLostFocus(DataGrid dg, bool value)
    {
        dg.SetValue(IsDeselectOnLostFocusProperty, value);
    }
}

Then:

<Style TargetType="{x:Type DataGrid}">
    <Setter Property="helpers:DataGridBehavior.IsDeselectOnLostFocus" Value="True"/>
</Style>

OTHER TIPS

A better way to achieve your actual goal of de-selecting the selected item is to bind an object of the same type as those in the collection data bound to the DataGrid.ItemsSource property to the DataGrid.SelectedItem property. When you want to deselect the selected item, you simply set this object to null:

<DataGrid ItemsSource="{Binding Items}" SelectedItem="{Binding Item}" />

In view model:

Item = null; // de-selects the selected item
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top