Происходит то, что ваши триггеры срабатывают последовательно, а не одновременно.Вот что происходит, событие
- MouseLeftButtonDown сработало
- Первый триггер активируется, проверяет
Visibility
, он виден, поэтому он меняет его на Свернутый - ВторойТриггер активирует, проверяет
Visibility
, что он свернут, поэтому он меняет его на Visible
Чистый результат в том, что он застрял в состоянии Visible.Вы можете убедиться в этом, изменив порядок триггеров - результат застрянет в свернутом состоянии.
Один из способов обойти это, не требующий кода для каждого экземпляра, - это использовать Converter
, который«переворачивает», видимый для рухнувшего.затем вы можете использовать ChangePropertyAction
для установки значения, которое определяется через привязку через этот конвертер, например
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<ec:ChangePropertyAction
TargetName="stackPanel"
PropertyName="Visibility"
Value="{Binding Visibility,
Converter={StaticResource VisibilityToOpposite},
ElementName=stackPanel}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
Преобразователь выглядит так,
public class VisibilityToOpposite : System.Windows.Data.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo cultureInfo)
{
Visibility vis = (Visibility)value;
return (vis == Visibility.Collapsed) ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo cultureInfo)
{
throw new NotImplementedException();
}
}
Великолепная вещьэтот метод заключается в том, что конвертер можно использовать повторно, а также не ограничиваться двумя состояниями, например
public class StringToNextString : System.Windows.Data.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo cultureInfo)
{
string s = (string)value;
List<string> allStrings = (parameter as string).Split(new char[] { '|' }).ToList();
// Find the index of the next string along
int i = allStrings.IndexOf(s);
i = (i + 1) % allStrings.Count;
return allStrings[i];
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo cultureInfo)
{
throw new NotImplementedException();
}
}
, а затем вызывать с помощью ConverterParameter строк с разделителями трубы циклический переход, например,
Value="{Binding Text, ConverterParameter=one|two|three,
Converter={StaticResource StringToNextString},
ElementName=stackPanel}"