change property of a group of buttons [duplicate] - wpf

I want to change the background of a MenuItem when the MenuItem is pressed.
<Style x:Key="{x:Type MenuItem}" TargetType="MenuItem">
<Style.Triggers>
<Trigger Property="MenuItem.IsPressed" Value="True">
<Setter Property="MenuItem.Background" Value="#FFE389" />
<Setter Property="MenuItem.BorderBrush" Value="#C2762B" />
</Trigger>
</Style.Triggers>
</Style>
I tried doing the above, but the trigger does not seem to work. Is the Trigger wrong?
Update: It works for the event IsMouseOver but IsPressed does not seem to work
Update 2: It works for TopLevelMenuItems but does not work for TopLevelMenuHeaderItems.

Try this...which does not preface the property names with MenuItem and modify your TargetType and x:Key syntax...
<Style x:Key="MyStyle" TargetType="{x:Type MenuItem}">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#FFE389" />
<Setter Property="BorderBrush" Value="#C2762B" />
</Trigger>
</Style.Triggers>
</Style>
EDIT:
Based on your updates take a look at how a default MenuItem is constructed via XAML. This should get you where you need to go in providing styling for the varying parts of the MenuItem. Note the use of the Role property within the MenuItem style dealing with the headers and items at both the top level and sub level.

Related

Trigger event in ViewModel when ListBoxItem has hover over

Issue
I have a Listbox that displays a list of images. I want to be able to hover over an image and for it to display the image in a bigger size. I am able to get the hover effect and for it to display some text i entered, but i need the image to change for different ListBoxItems.
Code
Here is the code I have used to get the hover effects:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="5,0,5,5" />
<Setter Property="Height" Value="140"/>
<Setter Property="Width" Value="200"/>
<Style.Triggers>
<Trigger Property="Control.IsMouseOver" Value="True">
<Setter Property="ToolTip" Value="{Binding IMAGEHERE}"></Setter>
<Setter Property="Control.Background" Value="#d64b36" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
So as you can see I have the tooltip but i need to image to be bound to the value from the ViewModel.
If an event in my ViewModel could get triggered when I hovered over a ListBoxItem it should solve my issue.
I think you can set the ToolTip with the Image control.
<Style.Triggers>
<Trigger Property="Control.IsMouseOver" Value="True">
<Setter Property="Control.ToolTip">
<Setter.Value>
<Image Source="{Binding Imagepath}" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
then, you can pass the source as Imagepath property from your ViewModel. I haven't tested this.

Sharing control templates between different button types

I want to define a style for ButtonBase and then extend that style in different ways for Togglebutton and Button. I want something like this:
<!-- Base Style -->
<Style x:Key="ButtonBaseStyle" TargetType="ButtonBase">
<Style.Resources>
<ControlTemplate x:Key="NormalStyle" TargetType="ButtonBase">...</ControlTemplate>
<ControlTemplate x:Key="HoverStyle" TargetType="ButtonBase">...</ControlTemplate>
</Style.Resources>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Template" Value="{StaticResource HoverStyle}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Template" Value="{StaticResource NormalStyle}" />
</Trigger>
</Style.Triggers>
</Style>
<!-- Toggle Button -->
<Style x:Key="ToggleButtonStyle" TargetType="ToggleButton" BasedOn="ButtonBaseStyle">
<Style.Resources>
<ControlTemplate x:Key="CheckedStyle" TargetType="ToggleButton">...</ControlTemplate>
</Style.Resources>
<Style.Triggers>
<!-- ToggleButton should inherit the triggers defined in ButtonBaseStyle; adding the additional trigger specific to ToggleButton here -->
<Trigger Property="IsChecked" Value="True">
<Setter Property="Template" Value="{StaticResource CheckedStyle}" />
</Trigger>
</Style.Triggers>
</Style>
The style declaration for ToggleButton is wrong. WPF does not allow styles to inherit like that. I want to know if I can achieve this effect in any other way. Note that I am aware that I can make the control templates global and use them selectively for different button classes. That is what I am doing now but I would like to avoid that.
Actually the proposed way works, you just have one syntax error.
Replace:
BasedOn="ButtonBaseStyle"
With:
BasedOn="{StaticResource ButtonBaseStyle}"

Trigger on Text in TextBox

I have this code:
<Style x:Key="qwe" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Text" Value="qwe">
<Setter Property="IsEnabled" Value="False"/>
</Trigger>
</Style.Triggers>
</Style>
But when I have "qwe" in TextBox, It is still enabled.
What is wrong?
You referenced the style on some TextBox, right?
<TextBox Style="{StaticResource qwe}"/>
Works for me...
Make sure you don't override the trigger by setting IsEnabled on the TextBox itself.

How to bind Background color to another IsSelected Background

I want to bind the selected Background color of MyDataGrid to another IsSelected Background color so they share the same color. I'm thinking it can be done something like below. How can I do it?
<DataGrid.Resources>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="{Binding ElementName=OtherDataGrid, Path=??Background??" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
The best way to share the background is to use a StaticResource.
You can create a brush in resources and refer that in both the data grids.
Like:
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource selectedCellBackground}" />
</Trigger>
</Style.Triggers>
Another way is to declare a notify property in the view model and bind both colors to it.

DataGridCell.IsEditMode?

How Can I know if the DataGridCell is currently in edit mode (not IsSelected), I mean, for example a DataGridTextColumn cell is clicked it becomes a TextBox and not a TextBlock, that's what I call IsEditMode.
I wanna set a trigger-setter for this mode.
EDIT:
I tried to set a general style for DataGridCell.IsEditing but it doesn't seem to do anything.
Here is a snippet of my current code:
<Style TargetType="{x:Type tk:DataGridCell}">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{x:Null}"/>
</Trigger>
<Trigger Property="IsEditing" Value="True">
<Setter Property="BorderBrush" Value="#FF62B6CC"/>
<Setter Property="Background" Value="#FFF4F4F4"/>
</Trigger>
</Style.Triggers>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderThickness" Value="0.5"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
</Style>
Thanks.
Here's how to do it:
<Trigger Property="IsEditing" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridCell">
<TextBox Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Content.Text, Mode=TwoWay, UpdateSourceTrigger=Default}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
then style the textbox as you please
If you take a look at DataGridCell.cs file, IsEditing should be good way to find out if cell is in edit mode. But you can't set this property from style, because there is local value assignment in DataGridCell class (which has higher priority from style setter).
So, the answer would be: it should work from trigger, but it will not from the style setter.
Update: Shimmy, it really works. Snoop your application, make sure DataGridCell is using your implicit style. Select DataGridCell in the tree, and check its background property. Every time you go in Edit mode it is updated. But you don't see it, by default, since TextBox doesn't inherit Background property. But that's another story. I think you can tweak CellEditingTemplate to make it working.
The proper way to turn on edit mode is to find the DataGridCell's parent DataGrid and call BeginEdit() on that. If you set it directly, you're sidestepping a lot of DataGrid goo that maintains proper state transitions.

Resources