GridSplitter переопределяет стиль триггера ColumnDefinition? - PullRequest
11 голосов
/ 18 декабря 2011

Я столкнулся со странной проблемой ...
Похоже, изменение размера столбцов Grid с помощью GridSplitter отключает (или иным образом деактивирует) триггер, определенный для столбца Grid.

Вот мои настройки:

Сетка имеет 3 столбца, определяемых следующим образом:

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
    <ColumnDefinition>
        <ColumnDefinition.Style>
            <Style>
                <Setter Property="ColumnDefinition.Width" Value="Auto"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=OpenItemViewModels.Count}" Value="0">
                        <Setter Property="ColumnDefinition.Width" Value="0"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ColumnDefinition.Style>
    </ColumnDefinition>
    <ColumnDefinition>
        <ColumnDefinition.Style>
            <Style>
                <Setter Property="ColumnDefinition.Width" Value="4*"/>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=OpenItemViewModels.Count}" Value="0">
                        <Setter Property="ColumnDefinition.Width" Value="0"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ColumnDefinition.Style>
    </ColumnDefinition>
</Grid.ColumnDefinitions>

Ожидается, что когда в столбце третий нет элементов, составляющих ItemsSource для элемента управления, ширина будет присвоена второму и третьему столбцам (в которых размещается GridSplitter и элемент управления вспомогательными элементами, соответственно).

Это работает хорошо, пока я не касаюсь Splitter (когда все вкладки во вспомогательном элементе управления закрыты, остается видимым только первый столбец).
Проблемы начинаются, если я перемещаю разделитель, таким образом эффективно изменяя пропорцию между столбцами ## 0 и 2. В таком сценарии ширина этих столбцов не сбрасывается, когда все элементы в правом элементе управления закрыты.

Я подозреваю, что это как-то связано с тем, что GridSplitter "перекрывает" мои определения в XAML.

Может кто-нибудь подтвердить / опровергнуть эту теорию и предложить, как обойти эту проблему?

Ответы [ 3 ]

18 голосов
/ 16 ноября 2012

У меня была такая же проблема для определения строки.Gridsplitter переопределит все, что мы даем в стиле или сеттерах.Это может быть решено с помощью анимации (поскольку анимация имеет самый высокий приоритет в разрешении значения свойства зависимости).Сделайте то же самое для третьего столбца.

<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition>
    <ColumnDefinition.Style>
        <Style>
            <Setter Property="ColumnDefinition.Width" Value="Auto" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=OpenItemViewModels.Count}" Value="0">
                    <DataTrigger.EnterActions>
                        <BeginStoryboard Name="BeginStoryboard1">
                            <Storyboard>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Width">
                                    <ObjectAnimationUsingKeyFrames.KeyFrames>
                                        <DiscreteObjectKeyFrame KeyTime="0:0:0"
                                                                Value="{x:Static GridLength.Auto}" />
                                    </ObjectAnimationUsingKeyFrames.KeyFrames>
                                </ObjectAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.EnterActions>
                    <DataTrigger.ExitActions>
                        <RemoveStoryboard BeginStoryboardName="BeginStoryboard1" />
                    </DataTrigger.ExitActions>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ColumnDefinition.Style>
</ColumnDefinition>

2 голосов
/ 11 ноября 2015

Я разработал вспомогательный класс, который помогает решить проблему складных столбцов / строк, размер которых также изменяется с помощью GridSplitter.

public class CollapsibleRowDefinition : RowDefinition
{
    public static readonly DependencyProperty IsCollapsedProperty = DependencyProperty.Register(
        "IsCollapsed",
        typeof(bool),
        typeof(CollapsibleRowDefinition),
        new FrameworkPropertyMetadata(
            false,
            (s,e) => { ((CollapsibleRowDefinition) s).IsCollapsed = (bool)e.NewValue; }));

    private bool isCollapsed = false;

    public CollapsibleRowDefinition()
    {
        DependencyPropertyDescriptor.FromProperty(RowDefinition.HeightProperty, typeof(RowDefinition)).AddValueChanged(this,
            (sender, args) =>
            {
                if (!this.IsCollapsed)
                {
                    this.ExpandedHeight = this.Height;
                }
            });
    }

    public GridLength CollapsedHeight { get; set; }
    public GridLength ExpandedHeight { get; set; }

    public bool IsCollapsed
    {
        get { return this.isCollapsed; }
        set
        {
            if (this.isCollapsed != value)
            {
                this.isCollapsed = value;
                this.Height = value ? this.CollapsedHeight : this.ExpandedHeight;
            }
        }
    }
}

Разметка затем выглядит следующим образом

        <Grid.RowDefinitions>
            <RowDefinition Height="40"/>
            <RowDefinition Height="2*"/>
            <RowDefinition Height="5"/>
            <c:CollapsibleRowDefinition CollapsedHeight="20" ExpandedHeight="*" IsCollapsed="{Binding ElementName=Btn_BottomCollapse, Path=IsChecked}"/>
        </Grid.RowDefinitions>
        <GridSplitter Grid.Row="2" HorizontalAlignment="Stretch"
                      IsEnabled="{Binding ElementName=Btn_BottomCollapse, Path=IsChecked}"/>
0 голосов
/ 24 марта 2012

У меня была такая же проблема ...

Единственное, что мне удалось отработать, было что-то вроде этого:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" x:Name="theColumn"/>
        <ColumnDefinition Width="1*"/>
    </Grid.ColumnDefinitions>
    <Expander Grid.Column="0" x:Name="theExpander" Expander.Collapsed="theExpander_Collapsed">
        ...
    </Expander>
    <GridSplitter Grid.Column="0" HorizontalAlignment="Right" Width="5">
        <GridSplitter.Style>
            <Style TargetType="{x:Type GridSplitter}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=theExpander, Path=IsExpanded}" Value="False">
                        <Setter Property="Visibility" Value="Collapsed"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </GridSplitter.Style>
    </GridSplitter>
    <Grid Grid.Column="1">
        ...    
    </Grid>
</Grid>

И код позади:

    private void theExpander_Collapsed(object sender, RoutedEventArgs e)
    {
        theColumn.Width = GridLength.Auto;
    }

Я бы предпочел не делать этого, но попытка использовать триггер стиля в определении столбца просто не работает.

...