Trigger on ContextMenu.IsOpen in XAML - c#

Here's what I'm trying to do:
<Style x:Key="TreeViewItemStyle">
<Setter Property="TreeViewItem.ContextMenu" Value="{StaticResource ContextMenu}" />
<Style.Triggers>
<Trigger Property="TreeViewItem.ContextMenu.IsOpen" Value="True">
<Setter Property="TreeViewItem.BitmapEffect">
<Setter.Value>
<OuterGlowBitmapEffect GlowColor="Yellow" GlowSize="2"/>
</Setter.Value>
</Setter>
</Trigger>
</Style>
...
But it is obviously not working because Property="TreeViewItem.ContextMenu.IsOpen" is not recognized. Any suggestions to what I need to change?

You can bind to the IsOpened property of the context menu using a DataTrigger:
<DataTrigger Binding="{Binding ContextMenu.IsOpen, RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="Background" Value="Green"/>
</DataTrigger>
Unfortunately, since all of the items in TreeView share the same ContextMenu, that will highlight all of them at once. There doesn't seem to be a property that lets you find out which FrameworkElement opened the ContextMenu.
You could handle the ContextMenuOpening and ContextMenuClosing events on the TreeViewItem, since those will bubble up from the control that handled the click and pass through the right TreeViewItem. If you want to do it in XAML, you could use an EventTrigger to start a one-frame animation that changes your property. The cleanest option may be to write an attached behavior that handles the ContextMenuOpening and ContextMenuClosing events and sets an attached property to true when the context menu is open.

Related

WPF: Conditionally put focus on checkbox and button

I want to set focus on conditionally in a WPFform. Here I have two types of control. One is 'checkbox' and other one is button. The checkboxes are getting enabled on some condition, however the button control(s) are visible by default. I am able to put focus on button(s) whether checkboxes are getting enabled or not. Though checkboxes should get focus over button when checkboxes are getting enabled. Kindly, suggest an approach to achieve this please. I have used following code to achieve focus on button(s)
<Style x:Key="FocusElement" TargetType="Grid">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=chkCA, Path=IsVisible}" Value="True">
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=chkCA}"/>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=btnSaveAll, Path=IsVisible}" Value="True">
<Setter Property="FocusManager.FocusedElement" Value="{Binding ElementName=btnSaveAll}"/>
</DataTrigger>
</Style.Triggers>
</Style>
Thanks!

WPF Custom Control That Displays Content Inline or in a Popup

I am creating a custom WPF content control that has a DisplayMode property which can be:
Inline
Popup
When DisplayMode="Inline", my ControlTemplate can use a standard ContentPresenter like normal.
However, when DisplayMode="Popup", I want the Content to be displayed in a Popup control.
How should I solve this problem?
Does it have to happen purely in code when the DisplayMode property changes? How do I move the content of the Content property between a ContentPresenter and the Popup?
It looks like I was trying to make this more complex than it really is.
The solution to this was to create two separate ControlTemplate(s). One that displays inline and one that displays in a Popup control.
Next, all I had to do was create a couple style triggers that change the ControlTemplate based on the value of the DisplayMode property.
It looks like this:
<Style x:Key="MyControlStyle" TargetType="{x:Type my:MyControl}">
<Setter Property="Template" Value="{StaticResource InlineTemplate}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding DisplayMode}" Value="Inline">
<Setter Property="Template" Value="{StaticResource InlineTemplate}"/>
</DataTrigger>
<DataTrigger Binding="{Binding DisplayMode}" Value="Overlay">
<Setter Property="Template" Value="{StaticResource OverlayTemplate}"/>
</DataTrigger>
</Style.Triggers>
</Style>

Using trigger to change property of many items

I created a WPF custom control, which works fine.
It has a style which sets some properties and a template.
Now i want to change the control, so it has a 'Active' property.
If this is true it should use the Property 'ActiveBrush' for the Stroke
of some Rectangles in the Template, else it should use 'InactiveBrush'.
I want to use the ActiveBrush as the default Stroke, and change it to InactiveBrush
with a Trigger.
This works fine with one Rectangle when i use this:
<Trigger Property="Active" Value="False">
<Setter TargetName="Rec1" Property="Stroke" Value="{Binding Path=InactiveBrush, RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
But since I don't want to set each rectangle with a seperated setter, I am asking myself if it shouldn't be possible to set the property of all Rectangles in the Template with one Setter.
I already tried:
<Trigger Property="Active" Value="False">
<Setter Property="Rectangle.Stroke" Value="{Binding Path=InactiveBrush, RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
But this didn't work.
Has anyone a suggestion, how to implement this?
Thanks in advance.
#Robert Rossney - this style will not run since a target type of Rectangle doesn't have a property Active. But that is the right path to go, with a minor change:
<Style TargetType="Rectangle">
<Style.Triggers>
<DataTrigger Binding="{Binding Active, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MyControl}}}" Value="False">
<Setter Property="Stroke" Value="{Binding Path=InactiveBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MyControl}}}"/>
</DataTrigger>
</Style.Triggers>
</Style>
This style should be nested in Style.Resources of the control style or in ControlTemplate.Resources of the ControlTemplate for the control. This way you're localizing this style only to your control. Any Rectangle outside of your control will not be affected.
I'm sure you know this but are just overlooking it: If you want to apply a style to all controls of a type, create a style with a TargetType of that type and put it in your custom control's resource dictionary. If you still need to apply specific styles to individual controls of that type, define those styles using the BasedOn property.
So, in your MyControl.Resources element, you'd put:
<Style TargetType="Rectangle">
<Style.Triggers>
<Trigger Property="Active" Value="False">
<Setter Property="Stroke" Value="{Binding Path=InactiveBrush, RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
<Style>
<Style>
and any Rectangle that needed its own style would start like this:
<Style TargetType="Rectangle" BasedOn="{StaticResource {x:Type Rectangle}}">

problem in the textblock style

Hello I am trying to make a textblock that they should focus on the event to underline the text and add when you lose the focus off him.
this is possible?
While I'm not sure if this is supported in Silverlight, this is how you'd do it in WPF:
<xxx.Resources>
<Style x:Key="HoverUnderline" TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="TextDecorations" Value="Underline"/>
</Trigger>
</Style.Triggers>
</Style>
...
<TextBlock Style="{StaticResource HoverUnderline}"
Content="Point at me to underline."/>
(Another interpretation of your question: use IsFocused instead of IsMouseOver. That's a weirder interpretation though since normally text blocks can't receive focus.)

Changed Background Color of Element when Disabled

How would I change the background color of a TextBox Control in the Default Style Xaml to be a different color when the control is either Disabled or ReadOnly ?
You can achieve this with triggers in the style:
<TextBox>
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="IsReadOnly" Value="True">
<Setter Property="Background" Value="Green" />
</Trigger>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Im not at a PC at the moment (just mobile) but I think you can edit the template of your control and there are some Visual States for your some controls that define things like disabled states, mouse overs, etc... which you should be able to redefine?
The way I accomplished this was to create a Converter for the control.
When the control is bound to an object it detects if the control is Enabled from this object that it is bound to. Based upon this it sets the background color for the Textbox accordingly.

Categories