I have a listview with some items. Also I have two buttons, add and delete. I have implemented drag and drop functionality in order to drag a single listviewitem from listview to the delete button and then on delete button drop, delete the listview item.
When listview item is dragged from listview to delete button and mouse is over the button (during drap and drop operation and before drop on button) I want to change the button image. It is working if I create a data trigger on button on IsMouseOver property, but I only want to change the button image when mouse is over the delete button during drag and drop operation (before drop). How can I do this?
<Button AllowDrop="True" Drop="btnDrop_Drop" Height="64" Width="64" Margin="10" Click="Button_Click_Delete" Content="Delete">
<Button.Template>
<ControlTemplate>
<StackPanel>
<Image x:Name="image1" Visibility="Visible" Height="36" Width="36" Stretch="UniformToFill" Source="Resources/icons8-Trash Can-48.png"/>
<Image x:Name="image2" Visibility="Collapsed" Height="36" Width="36" Stretch="UniformToFill" Source="Resources/icons8-Trash Can-48-3.png"/>
<Label HorizontalAlignment="Center">Delete</Label>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="image1" Property="Visibility" Value="Collapsed" />
<Setter TargetName="image2" Property="Visibility" Value="Visible" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
You could use EventTriggers to handle the Drop Target Events.
<ControlTemplate>
<StackPanel>
<Image x:Name="image1" Opacity="1" ... />
<Image x:Name="image2" Opacity="0" ... />
...
</StackPanel>
<ControlTemplate.Resources>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<Trigger Property="Opacity" Value="0">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</Style.Triggers>
</Style>
<Storyboard x:Key="swapImages" TargetProperty="Opacity">
<DoubleAnimation Storyboard.TargetName="image1" To="0" Duration="0" />
<DoubleAnimation Storyboard.TargetName="image2" To="1" Duration="0"/>
</Storyboard>
<Storyboard x:Key="resetImages" TargetProperty="Opacity">
<DoubleAnimation Storyboard.TargetName="image1" To="1" Duration="0" />
<DoubleAnimation Storyboard.TargetName="image2" To="0" Duration="0"/>
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="DragOver">
<BeginStoryboard Storyboard="{StaticResource swapImages}"/>
</EventTrigger>
<EventTrigger RoutedEvent="DragLeave">
<BeginStoryboard Storyboard="{StaticResource resetImages}"/>
</EventTrigger>
<EventTrigger RoutedEvent="Drop">
<BeginStoryboard Storyboard="{StaticResource resetImages}"/>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
adressing Opacity instead of Visibility.
when defining Storyboards in Resources, their location in the xaml file is important. Resources should be defined first (before the Triggers using them) or initialization will fail.
Related
here is what im doing
i have a Buttons.xaml style file for styling my menu button
<!-- Menu button -->
<Style x:Key="MenuButton" TargetType="{x:Type Button}">
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Height" Value="20" />
<Setter Property="Width" Value="50" />
<Setter Property="Margin" Value="0" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="IsHitTestVisible" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border">
<Grid VerticalAlignment="{TemplateBinding VerticalAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}">
<Rectangle x:Name="rectangle" Width="20" Height="2" Fill="{StaticResource DarkGrayBrush}" Margin="0 0 0 0" HorizontalAlignment="Center" VerticalAlignment="Top" RenderTransformOrigin="-0, 0.5" />
<Rectangle x:Name="rectangle1" Width="20" Height="2" Fill="{StaticResource DarkGrayBrush}" Margin="0 5 0 0" HorizontalAlignment="Center" VerticalAlignment="Top" RenderTransformOrigin="-0, 0.5" />
<Rectangle x:Name="rectangle2" Width="20" Height="2" Fill="{StaticResource DarkGrayBrush}" Margin="0 10 0 0" HorizontalAlignment="Center" VerticalAlignment="Top" RenderTransformOrigin="-0, 0.5" />
<ContentPresenter />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="border" Value="{StaticResource FaintWhiteBrush}"/>
</Trigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="menuButton">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="gridMenu" Storyboard.TargetProperty="Width" From="0" To="100" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="gridMenu" Storyboard.TargetProperty="Width" From="100" To="0" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and here is my usercontrol view file
that has menu button itself with the styling and source name in my style that is supposed to be found by my event trigger when this button is clicked and slide out the grid
but its not finding it
<Grid>
<!-- Menu button -->
<Button x:Name="menuButton" Style="{StaticResource MenuButton}" />
<!-- Menu bar -->
<Grid x:Name="gridMenu" Background="White" Width="0" HorizontalAlignment="Left">
</Grid>
when i run this code above this is the error message i get
InvalidOperationException: Cannot find element 'menuButton' targeted by this EventTrigger.
thanks in advance
Triggers inside ControlTemplates (or DataTemplates) can only reference elements that are inside that template. The template doesn't "know" about anything outside of itself, so it can't interact with anything but its own parts.
If you want menuButton to interact with gridMenu, that has to be set up from a context/scope that knows about both of those things. In your case, this would be the UserControl where they are both declared.
If you wanted to implement something like this using an EventTrigger (with XAML only- no code), it would have to be done in the ControlTemplate of the Control that directly contained those two elements. Something like this:
<Control>
<Control.Template>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Name="menuButton"/>
<Grid Name="gridMenu" Background="Green" Grid.Row="1"/>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger SourceName="menuButton" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="gridMenu" Storyboard.TargetProperty="Width" From="0" To="100" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="gridMenu" Storyboard.TargetProperty="Width" From="100" To="0" Duration="0:0:0.3" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Control.Template>
</Control>
The above is an example showing how to place a trigger in a scope that contains both elements, so that one can affect another. It's not a finished solution, but it should give you an idea of what I mean.
Keep in mind that I've just copy/pasted your EventTriggers into my code. The triggers as you've written them only grow and then immediately shrink menuGrid, which I'm guessing isn't exactly what you want. You probably want it to grow, stay open, and then shrink at some later point. You'll need to work that out on your own (or ask another question), but assuming you want a second click of menuButton to close menuGrid, try using a ToggleButton instead of a normal Button and using EventTriggers in the Checked and Unchecked events.
One last thought: since you're making a UserControl you might want to consider declaring a Boolean property such as IsOpen and using that to trigger the menuGrid animation (via a DataTrigger) instead of having it triggered directly by Button click. This would let you open/close the menu from the Window that is housing the UserControl. All standard controls that have some sort of popup (such as ComboBox and Expander) have some such property that tells you the current state and allows you to change it from the outside.
(On clicking the menu item , the visibility of the textblock mentioned below should be changed, How can i achieve this using data binding)
**<MenuItem Header="Lat/Long Info" IsCheckable="True" IsChecked="True"/>**
</ContextMenu>
</Window.Resources>
<Grid>
<Button Content="MENU" Height="20" Width="100" Margin="0,10" HorizontalAlignment="Left" VerticalAlignment="Top">
<Button.LayoutTransform>
<RotateTransform Angle="-90"/>
</Button.LayoutTransform>
<Button.Style>
<Style TargetType="Button">
<Setter Property="Button.Background" Value="Black"/>
<Setter Property="Button.Foreground" Value="White"/>
<Setter Property="ContextMenu" Value="{StaticResource conmenu}"/>
<Style.Triggers>
<EventTrigger RoutedEvent="Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="ContextMenu.IsOpen">
<DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
**<TextBlock Text="Change my Visibility" Margin="50"></TextBlock>**
</Grid>
Please anyone help me with this issue , I am unable to find any solution
i want the WPF button behaves in a way on mouse over only i want to show content of button (its an image)
and also on mouseover i want the background as transparent + no border .
Button content is an image and i am giving a padding of 50 px . so mouse is anywhere near to 50px on button i can see the button content.
The xaml i used is
<Button Style="{StaticResource FadeOutButton}" Padding="50" Opacity="0" >
<Image Source="Images\myimage.JPG"></Image>
and
<Style x:Key="FadeOutButton" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<EventTrigger RoutedEvent="Control.MouseEnter">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Duration="0:0:1" To="1" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Control.MouseLeave">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Duration="0:0:1" To="0" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
What else i have to add to make the background transparent on mouseover in addition to current effect
Try this
<Window.Resources>
<Style x:Key="FadeOutButton" TargetType="{x:Type Button}">
<Style.Resources>
<Storyboard x:Key="MouseOverAnimation" >
<DoubleAnimation Duration="0:0:1" To="1" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
<Storyboard x:Key="MouseOutAnimation">
<DoubleAnimation Duration="0:0:1" To="0" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="Transparent" >
<ContentPresenter Margin="{TemplateBinding Padding}" HorizontalAlignment="Center" Content="{TemplateBinding Content}" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"/>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource MouseOverAnimation}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource MouseOutAnimation}" />
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Button Style="{StaticResource FadeOutButton}" Padding="50" Opacity="0" >
<Image Source="Screenshot_3.png"></Image>
</Button>
I am trying to create a designer like Visual Studio.
Suppose I have a Grid.
Inside that I have a TextBox and a TextBlock. For better understanding look at the sample code below:
<Page.Resources>
<Style x:Key="myStyle" TargetType="{x:Type Border}">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="2" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="DodgerBlue" />
</Trigger>
</Style.Triggers>
</Style>
</Page.Resources>
<Border Style="myStyle">
<Grid>
<Border Style="myStyle">
<TextBox ...... />
</Border>
<Border Style="myStyle">
<TextBlock ...... />
</Border>
</Grid>
</Border>
Now when I mouseOver on any of the element I want to get a border around it.
My Problems:
I get a border around grid as well as a border around textblock when mouse cursor is over textblock.
When my mouse cursor goes over empty area of grid the border is not shown.
Requirements :
when mouse cursor goes over textblock, the border around grid should become invisible.
when mouse cursor goes over empty area in grid, the border around grid should become visible.
Please suggest the changes that I should make in the above code to have the required functionality.
Why did you assign myStyle to the outter Border? Just leave that out.
1: I think, your idea with glowing parent border is not good. Because it will be blink whenever user hold mouse over the grid. Perhaps, it will annoy user :)
2: Try to set Grid.Background="Transparent".
Try this
<Grid Background="LightGray" >
<Grid.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation From="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Grid_Bd" Duration="0:0:0.1"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation From="1" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Grid_Bd" Duration="0:0:0.1"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Grid Height="50" Width="50">
<Border x:Name="TextBlock_Bd" Opacity="0" BorderBrush="Blue" BorderThickness="1"/>
<TextBlock Text="Hello !!" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation From="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="TextBlock_Bd" Duration="0:0:0.1"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation From="1" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="TextBlock_Bd" Duration="0:0:0.1"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
</Grid>
<Border x:Name="Grid_Bd" Opacity="0" BorderBrush="Red" BorderThickness="1"/>
</Grid>
When I put my mouse on 1st image, 2nd image will appear. When I leave my mouse on 1st image, 2nd image will straight away fade off. How to do to make 2nd image to keep on appear for a few second even after l leave off my mouse on the 1st image?
<EventTrigger RoutedEvent="Button.Click" SourceName="P">
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource showA}"/>
</EventTrigger.Actions>
</EventTrigger>
<Button Grid.Column="1" Command="{Binding Path=PressC}" CommandParameter="cam" Style="{StaticResource TransparentButton}">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image Name="1" Source="/W;component/Images/1.png" Height="100" />
<Image Name="2" Source="/W;component/Images/2.png" Height="200" Width="100" Margin="50,-33,-50,0" Visibility="Hidden" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="imgPressedKeyboard05" Storyboard.TargetProperty="Opacity" From="0" To="2" Duration="0:0:.5" BeginTime="0:0:0"/>
<DoubleAnimation Storyboard.TargetName="imgPressedKeyboard05" Storyboard.TargetProperty="Opacity" From="2" To="0" Duration="0:0:.5" BeginTime="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Setter Property="Panel.ZIndex" Value="999"/>
<Setter TargetName="pressed5" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
Use animations instead of a simple Setter. One in the EnterActions to make it visible, one in the ExitActions to hide it after a given time. To animate Visibility you can use an ObjectAnimationUsingKeyFrames.