我认为我所做的事情相当简单,我想我只是错过了一些东西。
我在另一个StackPanel内部有一个StackPanel。我想要做的是在点击一个外部时隐藏/显示内部的一个。
我在混合中有2个状态。首先使StackPanel折叠,另一个展开。
我向外部StackPanel添加了2个行为(GoToStateBaheviour)并将其触发器分配给MouseLeftButtonDown事件。在条件中的第一个行为中,我检查内部StackPanel是否已折叠,如果是,则切换到Expanded状态。 其他行为反之亦然 - 在条件中我检查内部StackPanel是否可见,如果是,则切换到Collapsed状态。
现在这两种行为都可以正常工作。但结合起来,不是机会。我试图将其中一个的事件名称更改为“ManipulationDelta”,然后两者都开始工作 - 但要激活我必须尝试拖动它。
似乎有2个行为附加到同一事件导致麻烦。你会推荐什么?
修改
我上传了整个解决方案,因此您可以在Blend中打开它 http://leteckaposta.cz/800017526
(该项目适用于WPF,而不是我对WP7的项目,但这不重要) 我将行为更改为ChangePropertyAction,这应该使它更容易阅读。它们有两个 - 都对MouseLeftButtonDown做出反应,其中包含Visibility属性。其中一个将其更改为Visible,另一个更改为Collapsed。 但只有其中一个有效。我怀疑它总是“上层”(首先出现的那个)。随意测试一下
CODE
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
x:Class="WpfApplication1.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Grid x:Name="LayoutRoot">
<StackPanel Height="168" Width="305" HorizontalAlignment="Left" VerticalAlignment="Top" Background="#FF7C7070">
<TextBlock Height="59" TextWrapping="Wrap" Text="Outter">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<i:Interaction.Behaviors>
<ei:ConditionBehavior>
<ei:ConditionalExpression>
<ei:ComparisonCondition LeftOperand="{Binding Visibility, ElementName=stackPanel}" Operator="Equal">
<ei:ComparisonCondition.RightOperand>
<Visibility>Visible</Visibility>
</ei:ComparisonCondition.RightOperand>
</ei:ComparisonCondition>
</ei:ConditionalExpression>
</ei:ConditionBehavior>
</i:Interaction.Behaviors>
<ei:ChangePropertyAction TargetObject="{Binding ElementName=stackPanel}" PropertyName="Visibility">
<ei:ChangePropertyAction.Value>
<Visibility>Collapsed</Visibility>
</ei:ChangePropertyAction.Value>
</ei:ChangePropertyAction>
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeftButtonDown">
<i:Interaction.Behaviors>
<ei:ConditionBehavior>
<ei:ConditionalExpression>
<ei:ComparisonCondition LeftOperand="{Binding Visibility, ElementName=stackPanel}" Operator="NotEqual">
<ei:ComparisonCondition.RightOperand>
<Visibility>Visible</Visibility>
</ei:ComparisonCondition.RightOperand>
</ei:ComparisonCondition>
</ei:ConditionalExpression>
</ei:ConditionBehavior>
</i:Interaction.Behaviors>
<ei:ChangePropertyAction TargetObject="{Binding ElementName=stackPanel}" PropertyName="Visibility">
<ei:ChangePropertyAction.Value>
<Visibility>Visible</Visibility>
</ei:ChangePropertyAction.Value>
</ei:ChangePropertyAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
<StackPanel x:Name="stackPanel" Height="106" RenderTransformOrigin="0.489,-0.842" Background="#FF708B7C" Visibility="Hidden">
<TextBlock Height="50" Margin="74,0,65,0" TextWrapping="Wrap" Text="Inner"/>
</StackPanel>
</StackPanel>
</Grid>
</Window>
答案 0 :(得分:0)
正如您在Chris W.'s answer中所评论的那样,当您将两个触发器放在同一个事件中时,它们会相互竞争并相互抵消。您可以在其中一个触发器上使用MouseLeftButtonUp
来验证这一点。
事件背后的简单代码可以解决此问题。
<强> XAML 强>
<Grid x:Name="LayoutRoot">
<StackPanel Background="Red" MouseLeftButtonDown="OnMouseLeftButtonDown">
<TextBlock FontSize="22" Text="Outter" />
<StackPanel x:Name="stackPanel"
Height="75"
Background="Yellow">
<TextBlock FontSize="22" Text="Inner" />
</StackPanel>
</StackPanel>
</Grid>
代码背后
private void OnMouseLeftButtonDown( object sender, MouseButtonEventArgs e )
{
stackPanel.Visibility = stackPanel.Visibility == Visibility.Visible
? Visibility.Collapsed
: Visibility.Visible;
e.Handled = true;
}
答案 1 :(得分:0)
发生的事情是你的触发器按顺序而不是同时触发。这是正在发生的事情,
Visibility
,它是可见的,因此它将其更改为折叠Visibility
它是否已折叠,因此将其更改为“可见”最终结果是它处于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}"