如何编写数据触发器以通过在 WPF 中单击动态按钮打开弹出窗口?
How to Write a Data Trigger to open Popup by Clicking dynamic Button in WPF?
我的 WPF 应用程序中有一个动态按钮,单击任何一个按钮时,弹出窗口应打开,相应的按钮应将背景颜色变为橙色,按钮的其余部分应为默认背景颜色使用 DataTrigger 和另一个条件,在弹出窗口关闭时,相应的按钮背景颜色应变为默认颜色。
Note: I Can't able to give Name for the Buttons because of Dynamic
Creation. Here I placed 5 Buttons without Name Property, Consider the
Button as Dynamic Creation
我的XAML源代码是
<Grid>
<Grid Height="30px" VerticalAlignment="Top" Margin="0,50,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100px"/>
<ColumnDefinition Width="100px"/>
<ColumnDefinition Width="100px"/>
<ColumnDefinition Width="100px"/>
<ColumnDefinition Width="100px"/>
</Grid.ColumnDefinitions>
<Button Content="One" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75"/>
<Button Content="Two" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75"/>
<Button Content="Three" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75"/>
<Button Content="Four" Grid.Column="3" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75"/>
<Button Content="Five" Grid.Column="4" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75"/>
</Grid>
<Grid>
<Popup Name="sPop" Placement="Mouse" StaysOpen="False">
<Grid>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap" Text="Welcome to Popup Screen"/>
</Grid>
</Popup>
</Grid>
</Grid>
我试图在不使用 DataTrigger
的情况下实现您的要求。
这是用于更改背景的简单样式触发器:
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="Button.IsFocused" Value="True">
<Setter Property="Button.Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
您的每个按钮都可以处理 Click
事件:
<Button Content="One" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75" Click="Button_Click" />
...
我们需要以某种方式处理您的 Popup
。我刚刚命名它:
<Popup Name="popup" Placement="Mouse" StaysOpen="False">
...
点击事件很简单:
private void Button_Click(object sender, RoutedEventArgs e) {
var button = sender as Button;
if (popup.IsOpen) { popup.IsOpen = false; }
popup.PlacementTarget = button;
popup.IsOpen = true;
}
所以它会如您所愿。
您不能使用 DataTriggers 执行此操作。 DataTriggers 适用于 Data-Based 场景,因此如果您使用 DataBinding,则使用它们。
推荐方法:
为您的弹出窗口指定一个名称。并使用行为。
<Button ...>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:Interaction.Behaviors>
<ei:ConditionBehavior>
<ei:ConditionalExpression>
<ei:ComparisonCondition LeftOperand="{Binding IsFocused, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" RightOperand="True"/>
</ei:ConditionalExpression>
</ei:ConditionBehavior>
</i:Interaction.Behaviors>
<ei:ChangePropertyAction TargetObject="{Binding ElementName=Popup1}" PropertyName="IsOpen" Value="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
要使用 Blend 程序集:
添加对 System.Windows.Interactivity
和 Microsoft.Expression.Interactions
以及以下命名空间的引用:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
还原源按钮的旧背景:
<Button>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:Interaction.Behaviors>
<ei:ConditionBehavior>
<ei:ConditionalExpression>
<ei:ComparisonCondition LeftOperand="{Binding IsFocused, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" RightOperand="True"/>
</ei:ConditionalExpression>
</ei:ConditionBehavior>
</i:Interaction.Behaviors>
<!-- Store Button's old Background -->
<ei:ChangePropertyAction TargetObject="{Binding ElementName=Popup1}" PropertyName="Tag" Value="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}"/>
<!-- Change Button's Background -->
<ei:ChangePropertyAction PropertyName="Background" Value="Purple"/>
<!-- Open Popup -->
<ei:ChangePropertyAction TargetObject="{Binding ElementName=Popup1}" PropertyName="IsOpen" Value="True"/>
<!-- Save this Button, Popup will use it to revert back its old Background -->
<ei:ChangePropertyAction TargetObject="{Binding ElementName=Popup1}" PropertyName="PlacementTarget" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Popup x:Name="Popup1" Placement="Mouse" StaysOpen="False">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closed">
<ei:ChangePropertyAction
TargetObject="{Binding PlacementTarget, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Popup}}"
PropertyName="Background"
Value="{Binding Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Popup}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap" Text="Welcome to Popup Screen"/>
</Grid>
</Popup>
我的 WPF 应用程序中有一个动态按钮,单击任何一个按钮时,弹出窗口应打开,相应的按钮应将背景颜色变为橙色,按钮的其余部分应为默认背景颜色使用 DataTrigger 和另一个条件,在弹出窗口关闭时,相应的按钮背景颜色应变为默认颜色。
Note: I Can't able to give Name for the Buttons because of Dynamic Creation. Here I placed 5 Buttons without Name Property, Consider the Button as Dynamic Creation
我的XAML源代码是
<Grid>
<Grid Height="30px" VerticalAlignment="Top" Margin="0,50,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100px"/>
<ColumnDefinition Width="100px"/>
<ColumnDefinition Width="100px"/>
<ColumnDefinition Width="100px"/>
<ColumnDefinition Width="100px"/>
</Grid.ColumnDefinitions>
<Button Content="One" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75"/>
<Button Content="Two" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75"/>
<Button Content="Three" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75"/>
<Button Content="Four" Grid.Column="3" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75"/>
<Button Content="Five" Grid.Column="4" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75"/>
</Grid>
<Grid>
<Popup Name="sPop" Placement="Mouse" StaysOpen="False">
<Grid>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap" Text="Welcome to Popup Screen"/>
</Grid>
</Popup>
</Grid>
</Grid>
我试图在不使用 DataTrigger
的情况下实现您的要求。
这是用于更改背景的简单样式触发器:
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="Button.IsFocused" Value="True">
<Setter Property="Button.Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
您的每个按钮都可以处理 Click
事件:
<Button Content="One" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" Width="75" Click="Button_Click" />
...
我们需要以某种方式处理您的 Popup
。我刚刚命名它:
<Popup Name="popup" Placement="Mouse" StaysOpen="False">
...
点击事件很简单:
private void Button_Click(object sender, RoutedEventArgs e) {
var button = sender as Button;
if (popup.IsOpen) { popup.IsOpen = false; }
popup.PlacementTarget = button;
popup.IsOpen = true;
}
所以它会如您所愿。
您不能使用 DataTriggers 执行此操作。 DataTriggers 适用于 Data-Based 场景,因此如果您使用 DataBinding,则使用它们。
推荐方法:
为您的弹出窗口指定一个名称。并使用行为。
<Button ...>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:Interaction.Behaviors>
<ei:ConditionBehavior>
<ei:ConditionalExpression>
<ei:ComparisonCondition LeftOperand="{Binding IsFocused, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" RightOperand="True"/>
</ei:ConditionalExpression>
</ei:ConditionBehavior>
</i:Interaction.Behaviors>
<ei:ChangePropertyAction TargetObject="{Binding ElementName=Popup1}" PropertyName="IsOpen" Value="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
要使用 Blend 程序集:
添加对 System.Windows.Interactivity
和 Microsoft.Expression.Interactions
以及以下命名空间的引用:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
还原源按钮的旧背景:
<Button>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:Interaction.Behaviors>
<ei:ConditionBehavior>
<ei:ConditionalExpression>
<ei:ComparisonCondition LeftOperand="{Binding IsFocused, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" RightOperand="True"/>
</ei:ConditionalExpression>
</ei:ConditionBehavior>
</i:Interaction.Behaviors>
<!-- Store Button's old Background -->
<ei:ChangePropertyAction TargetObject="{Binding ElementName=Popup1}" PropertyName="Tag" Value="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}"/>
<!-- Change Button's Background -->
<ei:ChangePropertyAction PropertyName="Background" Value="Purple"/>
<!-- Open Popup -->
<ei:ChangePropertyAction TargetObject="{Binding ElementName=Popup1}" PropertyName="IsOpen" Value="True"/>
<!-- Save this Button, Popup will use it to revert back its old Background -->
<ei:ChangePropertyAction TargetObject="{Binding ElementName=Popup1}" PropertyName="PlacementTarget" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Popup x:Name="Popup1" Placement="Mouse" StaysOpen="False">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Closed">
<ei:ChangePropertyAction
TargetObject="{Binding PlacementTarget, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Popup}}"
PropertyName="Background"
Value="{Binding Tag, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Popup}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap" Text="Welcome to Popup Screen"/>
</Grid>
</Popup>