DataTrigger, который не отменяет себя, когда условие больше не выполняется - PullRequest
1 голос
/ 14 декабря 2011

Есть ли способ сделать что-то похожее на следующее?

<Style TargetType="{x:Type: TreeViewItem}">
    <Style.Triggers>
        <DataTrigger Binding="~Complex Binding~" Value="True" DoNotUnset="True">
            <Setter Property="IsExpanded" Value="True"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

Что я в основном хотел бы, чтобы это был "No Undo DataTrigger", если хотите.Когда Значение больше не является «Истиной», я не хочу, чтобы оно возвращало «IsExpanded» к своему предыдущему значению.

Вот моя попытка сделать это, используя действия ввода, но это также имеет проблемы.

<Style TargetType="{x:Type: TreeViewItem}">
    <Style.Triggers>
        <DataTrigger Binding="~Complex Binding~" Value="True">
            <DataTrigger.EnterActions>
                <BeginStoryboard>
                    <BeginStoryboard.Storyboard>
                        <Storyboard>
                            <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="(IsExpanded)" Duration="00:00:01" FillBehavior="Stop">
                                <BooleanKeyFrameCollection>
                                    <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="True"/>
                                </BooleanKeyFrameCollection>
                            </BooleanAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard.Storyboard>
                </BeginStoryboard>
            </DataTrigger.EnterActions>
        </DataTrigger>
    </Style.Triggers>
</Style>

Во-первых, это безумно многословно, а во-вторых, это работает только во время BooleanAnimationUsingKeyFrames.Если я изменю FillBehavior на «HoldEnd», то он будет выглядеть правильно, но теперь пользователь больше не может раскрывать элемент дерева с помощью щелчков (хотя, как ни странно, они все еще могут это делать с помощью клавиатуры).

Для тех, кто задается вопросом: да, я пытаюсь расширить все элементы в древовидном представлении путем привязки, потому что я не хочу создавать рекурсивный цикл ItemsGenerator.GetItemContainerFromIndex (i).Я все еще хотел бы использовать подобное «No Undo Datatigger» в других областях моего кода.

1 Ответ

1 голос
/ 17 января 2012

Я бы привязал ~ Complex Binding ~ к bool в ViewModel, который когда-то установлен в true, всегда true.

private bool _onceTrueAlwaysTrue = false;
public bool OnceTrueAlwaysTrue
{
    get
    {
         return _onceTrueAlwaysTrue;
    }
    set
    {
         if(value)
         {
            _onceTrueAlwaysTrue = true;
            OnPropertyChanged("OnceTrueAlwaysTrue");
         }
    }
}

затем привяжите это свойство к IsEnabled, и все будет в порядке. Если вы хотите сбросить его, просто создайте метод сброса, который устанавливает _onceTrueAlwaysTrue = false;

Что касается источника данных NoUndo, то, насколько я знаю, такого не существует. Вам придется каждый раз выполнять какую-то работу.

Свойства, измененные триггерами, автоматически сбрасываются на прежнее значение, когда условие триггера больше не выполняется. Триггеры оптимизированы для переходных состояний, которые, как ожидается, изменятся и вернутся в исходное состояние, такие как IsPressed на Button и IsSelected на ListBoxItem.

...