Felix D.
Felix D.

Reputation: 5103

Contract expander on losing focus

I need the expander to expand whenever a cell gets focus.

Beside from that I want the expander to contract whenever the cell loses focus.

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <Expander VerticalAlignment="Stretch"    
                  IsExpanded="{Binding Path=IsFocused,
                                       Mode=OneWay,
                                       RelativeSource={RelativeSource 
                                            Mode=FindAncestor, 
                                            AncestorType=DataGridCell},
                  UpdateSourceTrigger=LostFocus}">
        <!--Expander.Content-->
        </Expander>
    </DataTemplate>
</DataGirdTemplateColumn.CellTemplate>

This solution is only expanding but not contracting.

Where am I wrong ?

Notes:

DataGrid.SelectionMode="Single"
DataGrid.SelectionUnit="Cell"

Upvotes: 2

Views: 639

Answers (2)

Milan
Milan

Reputation: 616

"This solution is only expanding but not contracting."

click on your expander to expand it once, and then try to click somewhere else in your datagridcell, it will not work, the binding is destroyed the first time you expand manually and the expander will not expand automatically when datagridcell IsFocused is true anymore. same happens if you use oneway binding on a simple bool property in viewmodel.

EDIT:

try using this expander, i believe it might do just what you need:

.xaml

<local:MyExpander DataGridCellToObserve="{Binding RelativeSource={RelativeSource AncestorType=DataGridCell}}" >

.cs

public class MyExpander : Expander
{
    public MyExpander()
    {
        this.IsEnabled = false;
    }

    public DataGridCell DataGridCellToObserve
    {
        get { return (DataGridCell)GetValue(DataGridCellToObserveProperty); }    
        set { SetValue(DataGridCellToObserveProperty, value); }
    }

    public static readonly DependencyProperty DataGridCellToObserveProperty =
        DependencyProperty.Register("DataGridCellToObserve", typeof(DataGridCell), typeof(MyExpander), new PropertyMetadata(test));

    private static void test(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        (e.NewValue as DataGridCell).Selected += (d as MyExpander).setExpanded;
        (e.NewValue as DataGridCell).Unselected += (d as MyExpander).setExpandedFalse;
    }

    private void setExpanded(object sender, RoutedEventArgs e)
    {
        this.SetValue(IsExpandedProperty, true);
        this.IsEnabled = true;
    }

    void setExpandedFalse(object sender, RoutedEventArgs e)
    {
        this.SetValue(IsExpandedProperty, false);
        this.IsEnabled = false;
    }
}

Upvotes: 2

Eric
Eric

Reputation: 1847

Here is a solution with fewer dependencies (if you aren't already using Blend Behaviors):

<Expander Header="Hello" Content="Goodbye">
    <Expander.Style>
        <Style TargetType="Expander">
            <Style.Triggers>
                <EventTrigger RoutedEvent="LostFocus">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <BeginStoryboard.Storyboard>
                                <Storyboard TargetProperty="IsExpanded">
                                    <BooleanAnimationUsingKeyFrames>
                                        <DiscreteBooleanKeyFrame Value="False" KeyTime="0" />
                                    </BooleanAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard.Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
                <EventTrigger RoutedEvent="GotFocus">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <BeginStoryboard.Storyboard>
                                <Storyboard TargetProperty="IsExpanded">
                                    <BooleanAnimationUsingKeyFrames>
                                        <DiscreteBooleanKeyFrame Value="True" KeyTime="0" />
                                    </BooleanAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard.Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Style.Triggers>
        </Style>
    </Expander.Style>
</Expander>

Upvotes: 0

Related Questions