How to change button background color depending on bound command canexecute? - xaml

I Have a ItemTemplate in which is a simple button bound on a command, which can be executable or not depending on some property.
I'd like the color of this button's background to change if the command isn't executable.
I tried several methods, but I can't find anyway to do this purely in XAML (I'm doing this in a study context, and code behind isn't allowed).
Here's my code for the button :
<Button x:Name="Dispo" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Center" Width="30" Height="30"
Grid.Column="2" Grid.Row="0"
Command="{Binding AddEmpruntCommandModel.Command}"
CommandParameter="{Binding ElementName='flowCars', Path='SelectedItem'}"
vm:CreateCommandBinding.Command="{Binding AddEmpruntCommandModel}" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Button.Background" Value="Green"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Button.Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

You can specify your own template like that:
<Button Content="OK" Command="{Binding SomeCommand}">
<Button.Style>
<Style>
<Setter Property="Button.Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="Border" Background="Green">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>

Related

xaml style a border brush inside RibbonMenuItem

Im trying to style a RibbonMenuItem target type. the items inside are checkmark with border and contents. When IsMouseOver i want the border brush to be black.
The problem is there's not a borderbrush on the menuitem trigger property, and also im assuming the IsHighLighted is sort of like IsMouseOver property, so i make a seperate border style, and bind it to the style under trigger. i even tried to set the Opacity to a 1 value, but nothing seems to work
this is my code, as you can tell, im trying to override the ribbonmenuitem style
<Style x:Key="BorderThicknessStyle"
TargetType="{x:Type Border}">
<Setter Property="BorderThickness" Value="1"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderThickness" Value="2"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="{x:Type RibbonMenuItem}"
TargetType="{x:Type RibbonMenuItem}">
<Setter Property="HorizontalContentAlignment" Value="{Binding
Path=HorizontalContentAlignment,RelativeSource={RelativeSource AncestorType=
{x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment" Value="{Binding
Path=VerticalContentAlignment,RelativeSource={RelativeSource AncestorType=
{x:Type ItemsControl}}}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Padding" Value="3,2,3,2" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RibbonMenuItem}">
<Grid x:Name="MainGrid" SnapsToDevicePixels="True">
<Border x:Name="Border"
Background="{TemplateBinding Background}"
BorderThickness="{TemplateBinding
BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="2">
<Grid>
<Grid.ColumnDefinitions>
<!--Icon or check mark column-->
<ColumnDefinition MinWidth="22"
Width="Auto"
SharedSizeGroup="MenuItemIconColumnGroup" />
<!--Header column-->
<ColumnDefinition Width="*"/>
<!--Submenu arrow column-->
<ColumnDefinition Width="14" />
</Grid.ColumnDefinitions>
<Border x:Name="PART_SideBarBorder"
BorderThickness="1"
Background="{DynamicResource
ThemeWindowBackgroundBrush}"
BorderBrush="{Binding RelativeSource=
{RelativeSource TemplatedParent},
Path=Ribbon.BorderBrush}"
MaxWidth="17"
MaxHeight="17">
<Grid x:Name="SideBarOverlay"
Background="{TemplateBinding
Background}">
<Image x:Name="Image"
Width="16"
Height="16"
Margin="4,3,6,1"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Source="{TemplateBinding
ImageSource}" />
<Border x:Name="CheckMarkBorder"
BorderBrush="{TemplateBinding
BorderBrush}"
ClipToBounds="True">
<Path x:Name="CheckMark"
Visibility="Hidden"
Data="M 0 5 L 3 8 M 3 8 L 8 0"
Stretch="Uniform"
Stroke="{TemplateBinding
Foreground}"
StrokeEndLineCap="Round"
StrokeStartLineCap="Round"
Margin="2"
StrokeThickness="2" />
</Border>
</Grid>
</Border>
<ContentPresenter Grid.Column="1"
ContentSource="Header"
VerticalAlignment="Center"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True" />
<Path x:Name="Arrow"
Visibility="Collapsed"
Grid.Column="2"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Fill="{TemplateBinding Foreground}" />
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ImageSource" Value="{x:Null}">
<Setter TargetName="Image" Property="Visibility"
Value="Collapsed" />
</Trigger>
<Trigger Property="IsCheckable" Value="True">
<Setter TargetName="Arrow" Property="Visibility"
Value="Hidden" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="CheckMark" Property="Visibility"
Value="Visible" />
<Setter TargetName="CheckMarkBorder"
Property="Visibility" Value="Visible" />
<Setter TargetName="Image" Property="Visibility"
Value="Hidden" />
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter TargetName="PART_SideBarBorder"
Property="Style" Value="
{StaticResource BorderThicknessStyle}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Image" Property="Opacity"
Value="0.5" />
<Setter TargetName="Arrow" Property="Opacity"
Value="0.5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This works for me. In the ControlTemplate.Triggers, you want to add the DataTrigger instead of Trigger.
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsHighlighted}"
Value="True">
<Setter TargetName="PART_SideBarBorder" Property="BorderBrush"
Value="Black"/>
</DataTrigger>

Add Xaml hyperlink to rectangle

I am trying to add a hyperlink to a xaml rectangle and it's not working. I tried adding hyperlink with a button and it works. How can I add hyperlink to a group of rectangle for the code below.
How to give Hyperlink for below Code
<Rectangle Fill="Red" HorizontalAlignment="Left" Height="38" Margin="1038,74,0,0" Stroke="Black" VerticalAlignment="Top" Width="426"/>
<TextBlock HorizontalAlignment="Left" Margin="1173,82,0,0" TextWrapping="Wrap" Text="Pending Sites " VerticalAlignment="Top" Height="24" Width="142" Foreground="#FFF7F6F1" FontSize="20" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto">
<TextBlock.RenderTransform>
<CompositeTransform Rotation="-0.098"/>
</TextBlock.RenderTransform>
</TextBlock>
Code I tried with Button which is working fine
<Button Content="Click to go to desc page" Click="Button_Click_1" Margin="62,376,0,357"/>
private void Button_Click_1(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(dPlanner2x.MyPageDetails));
}
Rather than trying to turn a Rectangle into a click-able object, you are much better off if you apply a Style to a Button.
An example of a Style to change the look of a Button is given below:
<Style x:Key="btnCommand" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="rct"
TextBlock.Foreground="White"
Background="DarkGray"
BorderBrush="DarkGray"
BorderThickness="1"
Cursor="Hand"
UseLayoutRounding="True"
SnapsToDevicePixels="True"
Margin="10"
Height="24"
MinWidth="75">
<ContentPresenter TextBlock.FontStyle="Segoe UI Semibold"
TextBlock.FontSize="14"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="rct"
Property="TextBlock.Foreground"
Value="DarkGray" />
<Setter TargetName="rct"
Property="Background"
Value="LightGray" />
<Setter TargetName="rct"
Property="BorderBrush"
Value="DarkGray" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="rct"
Property="TextBlock.Foreground"
Value="DarkGray" />
<Setter TargetName="rct"
Property="Background"
Value="White" />
<Setter TargetName="rct"
Property="BorderBrush"
Value="LightGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Obviously, you will want something that looks completely different, but the Style template above can be easily modified to fit your needs.

How to stop style overwriting in wpf?

I create a WPF UserContorl and create a style for ListView in my UserContorl theme.
My ListView Style :
<Style TargetType="ListView" x:Key="ReminderListView">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<CheckBox Style="{StaticResource ReminderCheckBox}" IsChecked="{Binding IsSelected, Mode=TwoWay}" Content="{Binding Title, Mode=OneTime}"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
My ListView Style Work Correctly in UserContorl.
My used Xaml in UserControl:
<ListView Name="snoozeListView" Grid.Column="1" Style="{StaticResource ReminderListView}" ItemsSource="{Binding ReminderItems}" >
i use this UserControl in other WPF project which have a ListViewItem Style.
ListViewItem Style :
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Foreground" Value="{StaticResource ForegroundBrush}"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="Padding" Value="2,0,2,0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<StackPanel SnapsToDevicePixels="True" Margin="2,0,2,0">
<Grid x:Name="Grid" Background="Transparent">
<Rectangle x:Name="SelectedRect" IsHitTestVisible="False" Fill="{StaticResource SelectedBackgroundBrush}" Opacity="0"/>
<GridViewRowPresenter Height="Auto" Margin="2"/>
</Grid>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now ListViewItem style overwriting the ListView ItemTemplate Style which defined in user control theme.
How can i stop overwriting.

how to set the color of toggle button from style already defined in app xaml?

I had created a button and i want to change its color using style from app xaml.
But,i don't get the exact code and i am new to xaml.
Can any one help me with some example.
I am also confused to use which property to change color means background or foreground?
<Window
x:Class="ToolBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ToolBar"
Width="300"
Height="300">
<DockPanel>
<ToolBarTray
DockPanel.Dock="Top"
IsLocked="True"
Orientation="Horizontal">
<ToolBar
x:Name="ToolBar1">
<ToggleButton>
<ToggleButton.Style>
<Style
TargetType="{x:Type ToggleButton}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Label>Play</Label>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Label>Pause</Label>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Panel.Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
</ToolBar>
</ToolBarTray>
</DockPanel>
</Window>
Within a toolbar, the two statements:
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Panel.Background" Value="Transparent" />
causes the toggle button to appear in the normal state when the toggle button is checked, however nothing changes when you hover over the checked toggle button.
If I wrap the toggle button in another layout, say wrap layout:
<Window
x:Class="ToolBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ToolBar"
Width="300"
Height="300">
<WrapPanel>
<ToggleButton>
<ToggleButton.Style>
<Style
TargetType="{x:Type ToggleButton}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Label>Play</Label>
</DataTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Label>Pause</Label>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Panel.Background" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
</WrapPanel>
</Window>
the two statements:
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Panel.Background" Value="Transparent" />
You can find tutorial in the folowing url
http://social.msdn.microsoft.com/Forums/pl-PL/wpf/thread/7e565a41-0aad-40a3-a3c4-666c5caf38fe
Thanks
Deepak

How can I bind a data inside a style?

This XAML tag doesn't work:
<Label Content="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
in this XAML code:
<Style x:Key="textBoxStyle" TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="Background" Value="Red"/>
<!--<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />-->
<Setter Property="ToolTip">
<Setter.Value>
<StackPanel Orientation="Vertical">
<Label Background="AliceBlue" Content="Input Error"/>
<Label Content="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
</StackPanel>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
I want to pass (Validation.Errors)[0].ErrorContent data of a TextBox in a Label inside ToolTip property
Using RelativeSource Self on a Label will get you the Label as the source, whereas you want the TextBox. Try a RelativeSource FindAncestor:
<Label Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TextBox}}, Path=(Validation.Errors)[0].ErrorContent}" />