IsMouseOver trigger for DockPanel not firing unless children are hovered over - wpf

This question has been asked a couple of times before, but at this time, none of the answers I've found turned out to be working.
So I have a custom DockPanel with 2 child elements inside, 1 TextBox and 1 Image.
I intended to have the DockPanel change color on hover, so I put a Trigger inside of it. But currently, it only changes color if I hover over the children, whereas a hover over whitespace between elements doesn't do anything.
I've read similar posts which mentioned using isHitTestVisible, but it doesn't do anything.
Short version of my code is the following:
<DockPanel>
<!-- Change color on mouse hover -->
<DockPanel.Style>
<Style>
<Style.Triggers>
<Trigger Property="DockPanel.IsMouseOver" Value="True">
<Setter Property="DockPanel.Background" Value="#FFe6ffe6"/>
</Trigger>
</Style.Triggers>
</Style>
</DockPanel.Style>
<StackPanel Orientation="Vertical" DockPanel.Dock="Center">
<!-- TextBox and Image code here -->
</StackPanel>
</DockPanel>

Add this to your dock panel style.
<Trigger Property="DockPanel.IsMouseOver" Value="False">
<Setter Property="DockPanel.Background" Value="Transparent"/>
</Trigger>

Related

How do I point to a Context Menu's parent in XAML?

I've searched quite a bit but most of the solutions I found were from people asking on how to do it in C#. I wanted both to practice my XAML and reduce my already messy C# code so I decided to try it on XAML.
What I've Tried:
I've created a template for the Context Menu and here's my code:
<ControlTemplate TargetType="ContextMenu">
<Grid>
<!-- Some Content -->
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Parent.IsMouseOver, RelativeSource={RelativeSource TemplatedParent}}" Value="True">
<Setter Property="IsOpen" Value="True"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
My understanding of the code:
I imagined the hierarchy to be like this:
Parent UIControl (Can be a button, textbox, etc)
|---> Context Menu
|---> Template
So with my code Binding Parent.IsMouseOver, RelativeSource={RelativeSource TemplatedParent}, I expected it to work like this:
I've set my source to the TemplatedParent first (which I expected to be the Context Menu)
Now I'm trying to bind to the Parent (which is a UIControl of whoever uses the Context Menu) of my source (which at the moment I expect to be the TemplatedParent)
Here's the full code of everything involved with this:
Parent:
<Button Content="Button" ContextMenu="{DynamicResource ErrorPopup}"/>
Context Menu w/ Control Template (They're stored on a ResourceDictionary since they'll be reused by other controls to display each of their own Errors):
-
<ContextMenu x:Key="ErrorPopup" x:Shared="False">
<ContextMenu.Style>
<Style TargetType="ContextMenu">
<Setter Property="IsOpen" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContextMenu">
<Grid>
<!-- Some Content -->
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Parent.IsMouseOver, RelativeSource={RelativeSource TemplatedParent}}" Value="True">
<Setter Property="IsOpen" Value="True"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ContextMenu.Style>
</ContextMenu>
What I expect:
I expected the Context Menu to popup when I place my cursor on top of the Button.
UPDATE:
I've managed to make some progress, I tried changing my binding to:
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType=Button,Mode=FindAncestor}}" Value="True">
<Setter Property="IsOpen" Value="True"/>
</DataTrigger>
Unfortunately it's displaying some weird behavior wherein the MouseOver would show the context menu ONLY if I forcibly open a Context Menu beforehand by using my mouse's right click.
This doesn't work:
I hover over the Button
Context Menu doesn't show up
This works:
I right click the Button
Context Menu shows up
Closes quickly
Shows a Context Menu from the Mouse Over
I move the cursor away = Context Menu disappears
I move the cursor inside = Context Menu appears
Could this be because the context menu doesn't actually exist yet up until I explicitly open it through a mouse's right click? And after initializing it, only then will the triggers work?

WPF - How to Change Mouse Cursor Color

I am trying to change the color of the mouse cursor when it's hovering over a textbox, so that it's easier to see on a dark background.
I know how to change four things:
Textbox background color (.Background)
Textbox foreground color (.Foreground)
Textbox caret color (.CaretBrush)
Mouse cursor image (Mouse.OverrideCursor or this.Cursor)
I just can't change the mouse cursor color.
I came across a way to completely change the mouse cursor to a custom made cursor in another question someone posted: "Custom cursor in WPF?". But it seems overkill for just wanting to change the color, so that I can actually see where the mouse is.
The mouse cursor color actually changes to white automatically if the textbox has a black background. But does not change automatically if it has a dark background that isn't quite black.
It's this simple. Try changing the CaretBrush color. See sample code below.
<TextBox Text="This is some random text" CaretBrush="Blue" />
EDIT :
You can't change the color of the mouse color without defining a custom cursor, but you can change it's type. See the example below.
<Grid>
<TextBox Width="70" Height="20" CaretBrush="IndianRed" Text="TEST">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Pen" />
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Cursor" Value="Arrow" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</Grid>
If you want to change the cursor type see this post Custom cursor in WPF?
You can change colour of the cursor with using CaretBrush property at WPF.
For example:
<Style x:Key="TextBoxStyle" TargetType="TextBox">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="CaretBrush" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
You can add your own trigger conditions if you want.

Mouse Hower on TextBlock

The idea is when mouse howler above TextBlock, new Image is appear and it possible to click on it. When mouse leave the TextBlock - Image should disappear.
Meanwhile I came to this, but still unable to continue:
<Style x:Key="HoverHighlightTextStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="Margin" Value="3,0,3,0"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
</Trigger>
</Style.Triggers>
</Style>
Expected result
I suggest you to follow the below steps.
Create a stackpanel (orientation is set to horizontal) or any other appropriate control and add text box and image controls inside it.
Hide the borders of text box and the image controls so that only the stackpanel border is visible.
When the mouseover event fired, set the image control to be appeared.
When the mouseleave event fired, set the image control to be disappeared.
I haven't tested this. But this might help you to get an idea.
I find solution based on sa_ddam213 answer:
<TextBlock x:Name="txtblkSelectedItem" Text="My Textblock">
<TextBlock.ToolTip>
<ToolTip PlacementTarget="{Binding ElementName=txtblkSelectedItem}" Placement="Right" HorizontalOffset="-20">
<Image Source="http://stackoverflow.com/users/flair/1849109.png" Width="10" Height="10"/>
</ToolTip>
</TextBlock.ToolTip>
The idea, is positioning tooltip inside textblock can be achived by using ToolTip
Placement="Right" HorizontalOffset="-20"
properties

ContentControl change ContentTemplate on GotFocus

I have a UserControl which contains a ContentControl. When the user clicks this ContentControl I want to change its ContentTemplate, to make it "editable" (instead of labels display textboxes for example).
What I have is this:
<StackPanel>
<ContentControl Style="{DynamicResource ContainerStyleEditable}" GotFocus="ContentControl_GotFocus"></ContentControl>
</StackPanel>
and in userControl resources i have
<Style TargetType="{x:Type ContentControl}" x:Key="ContainerStyleEditable">
<Setter Property="ContentTemplate" Value="{DynamicResource ItemTemplateReadOnly}" />
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="ContentTemplate" Value="{DynamicResource ItemTemplateEditable}" />
</Trigger>
</Style.Triggers>
</Style>
This doe not work, it seems the GotFocus event never fires. What is the way to to this?
I usually base my triggers of IsKeyboardFocusWithin instead of IsFocused because often the focused element usually isn't the actual ContentControl, but rather a control inside it's Content.
Also, be sure that at least one control inside the ContentControl can accept focus so the control can get focus. If nothing inside the control can accept focus, your trigger will never fire.

Customize Expander to expand on mouse enter

I am using Expander in WPF to display my data. The default style for the Expander control contains a toggle button which shows/hides my content when I click on it.
How can I modify the style so that it expands when I hovers the mouse over the header and collapse when I move away?
Barebone setup should be this:
<Style TargetType="{x:Type Expander}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsExpanded" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
(Applies to the whole expander, not just the header. That would probably require messing with the template.)
It is possible to use databinding between isExpanded property an ismouseover:
IsExpanded="{Binding IsMouseOver, Mode=OneWay, RelativeSource={RelativeSource Self}}"

Resources