I have a Stack Panel, that contains three buttons. When a button is clicked I want the background to stay permanently changed, however it doesn't seem to working.
I've tried to set the background colour programmatically as I've written below however it doesn't seem to work. When I set the foreground colour programmatically that works, changing the colours as instructed. I think as I'm using a template for the buttons in the XAML, where I assign a background colour, has priority over a programmatic change.
Attempt at changing background:
AColour.Background = Brushes.Black;
BColour.Background = Brushes.Red;
CColour.Background = Brushes.Black;
Attempt to change foreground (which works):
AColour.Foreground = Brushes.Black;
BColour.Foreground = Brushes.Red;
CColour.Foreground = Brushes.Black;
XAML (Button Template):
<Window.Resources>
<ControlTemplate x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Border Name="body" Background="#AEEEEE" BorderThickness="0" BorderBrush="DimGray" Padding="2">
<ContentPresenter HorizontalAlignment="Left" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="body" Value="#12CCD3"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" TargetName="body" Value="#009DA2"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
XAML Button Declaration (Same for all 3 buttons except name):
<Button Cursor="Hand" x:Name="AColour" Height="40" Template="{StaticResource ButtonStyle}" Width ="100" Click="A_Click">
Is there any way (if the template is having priority) to overwrite the template and change the background programmatically?
Because you have set button's background to "#AEEEEE" explicit, so ,the button's background will not changed by code.
I think you should use TemplateBinding in you Template,like this:
<Border Background="{TemplateBinding Background}">
<ContentPresenter ...... />
</Border>
Related
my question is that
is there any way for implementation a button like bold Button in word when click its background will be change , ""with out get boolean var"" ,
that means I want to know is there ant event or trigger or visualstate in xaml order to implement a button style when click its style will be change(during Working like word) and its style will come back to Normal style when click again ?
image Bold Btn
The way to do this is with style triggers. Like so...
<ToggleButton Content="B" FontSize="20" Height="40" Width="40">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="FontWeight" Value="ExtraBold"/>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
I'm currently designing a minor application for a program our site will be using and have come across problem after problem regarding combo boxes. I've finally got it to the basic stage that it needs to be at, but I'm facing issues with styling the text so that it is centrally aligned and padded by 5 pixels for the current selected item. I've tried adding Setters to where I think is correct, I've tried adding VerticalContentAlignment="Center" to the main XAML file but nothing shifts it.
What I would also like to do is when the options are rolled over, they have a different background colour. I've tried adding a MouseOver Visual State to ComboBoxItem but to no avail. Apologies in advance for the lengthy code (and probably messy). It's been a learn on the go job with most of it coming from MSDN and then being edited as needed. Many thanks.
CODE: http://pastebin.com/gQpp2W3U
This is because the parameters HorizontalContentAlignment and VerticalContentAlignment not transferred to the ControlTemplate in ContentPresenter properly:
<ContentPresenter x:Name="ContentSite"
...
VerticalAlignment="Stretch"
HorizontalAlignment="Left">
</ContentPresenter>
In this case, the parameters are "sewn", should be as follows:
<ContentPresenter x:Name="ContentSite"
...
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}">
</ContentPresenter>
For dynamic background element necessary add a triggers in <ControlTemplate.Triggers> section, previously adding the name for the common Grid of ComboBox:
<ControlTemplate.Triggers>
...
<Trigger Property="SelectedValue" Value="BATTLEFIELD4">
<Setter TargetName="MainGrid" Property="Background" Value="Green" />
</Trigger>
<Trigger Property="SelectedValue" Value="CALLOFDUTY4">
<Setter TargetName="MainGrid" Property="Background" Value="Blue" />
</Trigger>
<Trigger Property="SelectedValue" Value="CS">
<Setter TargetName="MainGrid" Property="Background" Value="Red" />
</Trigger>
</ControlTemplate.Triggers>
Example of using:
<Window ...
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Window.Resources>
<x:Array x:Key="TestArray" Type="{x:Type sys:String}">
<sys:String>BATTLEFIELD4</sys:String>
<sys:String>CALLOFDUTY4</sys:String>
<sys:String>CS</sys:String>
</x:Array>
</Window.Resources>
<Grid>
<ComboBox SelectedIndex="0"
Foreground="White"
Background="Blue"
Height="60"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
ItemsSource="{StaticResource TestArray}" />
</Grid>
Also trivia added some details, the full version of the project can be downloaded here.
Output
In an attempt to use a Click event on a label I have found an example of using a button but applying a template to it so that it looks like a label. As shown below:
<Button Name="LooksLikeALabel" Canvas.Left="279" Canvas.Top="-37" Height="26" Width="48" Content="Words" Click="answer1Label_MouseUp" MouseEnter="answer1Label_MouseEnter" MouseLeave="answer1Label_MouseLeave">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Label x:Name="buttonLabel" Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Button.Template>
</Button>
Now I want to be able to change the colour of the text on mouse over. Changing the foreground on the button does nothing bot in the code behind and through the XAML. Changing the colour of the label foreground works through the XAML but for whatever reason I am unable to access the label through the code behind meaning I can't access any of the label controls through my C#.
Is there something I am missing to get control over the label in the code behind? Alternatively, is there a better way to have a click event on a label?
Put Trigger inside ControlTemplate of button:
<Button Name="LooksLikeALabel" Canvas.Left="279" Canvas.Top="-37" Height="26"
Width="48" Content="Words">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Label x:Name="buttonLabel" Content="{TemplateBinding Content}"/>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter TargetName="buttonLabel" Property="Foreground" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
I'm new to WPF, but searching internet for some days I couldn't figure out my problem.
After I programmatically change Foreground property, IsMouseOver trigger doesn't work. Please be tolerant and thank in advance :)
<Style x:Key="ZizaMenuItem" TargetType="{x:Type Button}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="Margin" Value="5,0,5,0"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Label FontSize="14" Content="{TemplateBinding Content}" Name="ZizaMenuItemText" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ZizaMenuItemText" Property="Foreground" Value="#ff0000"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<StackPanel Height="30" Name="ZizaMenu" Orientation="Horizontal" Margin="0,12,0,0" VerticalAlignment="Top">
<Label Content="ZIZA" FontSize="11" FontWeight="Bold" Foreground="Black" Height="25" Margin="20,0,10,0" />
<Button Name="ZizaMenuInteresting" Click="ZizaMenuItemClicked" Content="ИНТЕРЕСНОЕ" Style="{StaticResource ZizaMenuItem}" />
<Button Name="ZizaMenuBest" Click="ZizaMenuItemClicked" Content="ЛУЧШЕЕ" Style="{StaticResource ZizaMenuItem}" />
<Button Name="ZizaMenuAuto" Click="ZizaMenuItemClicked" Content="АВТО" Style="{StaticResource ZizaMenuItem}" />
</StackPanel>
private void ZizaMenuItemClicked(object sender, RoutedEventArgs e)
{
// get label object from template
Button zizaMenuItem = (Button)sender;
Label zizaMenuItemText = (Label)zizaMenuItem.Template.FindName("ZizaMenuItemText", zizaMenuItem);
// set Foreground color for all buttons in menu
foreach (var item in ZizaMenu.Children)
if (item is Button)
((Label)(item as Button).Template.FindName("ZizaMenuItemText", (item as Button))).Foreground = Brushes.Black;
// set desired color to clicked button label
zizaMenuItemText.Foreground = new SolidColorBrush(Color.FromRgb(102, 206, 245));
}
That is horrible code, do not mess with controls inside control templates, ever. Template.FindName is something only the control that is being templated should call internally to get its parts, and only those, everything else should be considered uncertain.
If you need to change a property template bind it, and then bind or set said property on the instance. In terms of precedence you need to make sure not to create a local value which overrides the triggers (that is what you did). You can use a Style and Setter on the Label to bind the default Foreground.
<Label.Style>
<Style TargetType="Label">
<Setter Property="Foreground" Value="{TemplateBinding Foreground}"/>
</Style>
</Label.Style>
Now you just need to set the Foreground of the Button itself, the Trigger should still internally have precedence over that Setter.
It has to do with dependency property value precedence. Local values have higher precedence than template triggers.
For more information read this: http://msdn.microsoft.com/en-us/library/ms743230.aspx
When a button gets pressed the background (Rectangle Fill) of the button changes. So the user can see what buttons have been pressed and what not.
Problem:
I use a trigger and a Togglebutton to perform the "IsChecked" to change the background.
But the background change may only happens 1 time.
For example:
Button Background = black --> PRESS --> Button Background = blue
But when i press the button again the Button BackGround changes back to black (since its a ToggleButton).
How can i make sure the background only changes 1 time?
EDIT: The button must remain enabled, because a user gives in a reason when they press the button. Meaning if they pick the wrong reason they are able to change it.
<Style x:Key="ButtonStyleReg" TargetType="{x:Type myClasses:RegButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid x:Name="registrationButton">
<Rectangle Name="rectangleBtn" Fill="#FF89959A" Height="Auto" RadiusY="15" RadiusX="15" Stroke="White" Width="Auto"/>
<TextBlock x:Name="reason" TextWrapping="Wrap"
Text="{Binding Reason, StringFormat=\{0\}}"
HorizontalAlignment="Center" Margin="0,7.5,0,0" Height="Auto"
VerticalAlignment="Top" FontWeight="Bold" >
</TextBlock>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True"/>
<!--<Trigger Property="IsDefaulted" Value="True"/>-->
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="rectangleBtn" Property="Fill" Value="blue" />
</Trigger>
<Trigger Property="IsEnabled" Value="False"/>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="10.667"/>
Listbox that implements the style:
<ListBox x:Name="lbRegistration" ItemsSource="{Binding RegBtns, ElementName=Window}" Background="{x:Null}"
BorderBrush="{x:Null}" Grid.Column="1"
ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Disabled" Height="75">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<myClasses:RegistrationButton x:Name="RegistrationButton" HorizontalAlignment="Center" Height="71" Width="148"
Margin="10,0,5,0"
Style="{DynamicResource ButtonStyleRegistration}"
Click="RegistrationButton_Click"
Title="{Binding Title}"
Oorzaak="{Binding Oorzaak}"
DuurStilstand="{Binding DuurStilstand,
Converter={StaticResource DateTimeConverter}}"
BeginStilstand="{Binding BeginStilstand}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Best Regards,
Pete
Very simple would be if you can access the rectangle from code behind:
rectangleBtn.Fill = Brushes.Blue;
If you can't access it - make yourself two styles.
The one that is the original style, the other one is the Blue Style which shall be applied when the user clicks.
In the code behind, on event Click="RegistrationButton_Click"
Set the Style to the BlueStyle.
RegistrationButton.Style = this.FindResource("ButtonStyleRegistration") as Style;
Since you always want it blue, this code is enough as it is. It will always make it Blue for you.
The first time, and any other time.
That way you achieve your requirement and the style will change only once.
When the window is loaded, it will load into the original style (the first style).
So put in your XAML the style "Black" and in the code behind as shown above.
Then this must be removed:
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="rectangleBtn" Property="Fill" Value="blue" />
</Trigger>
Then this:
<myClasses:RegistrationButton x:Name="RegistrationButton" HorizontalAlignment="Center" Height="71" Width="148"
Margin="10,0,5,0"
Style="{DynamicResource ButtonStyleRegistration}"
Click="RegistrationButton_Click"
Shall be:
<myClasses:RegistrationButton x:Name="RegistrationButton" HorizontalAlignment="Center" Height="71" Width="148"
Margin="10,0,5,0"
Style="{DynamicResource ButtonStyleRegBlack}"
Click="RegistrationButton_Click"
That is all.
If you're using an MVVM approach I would recommend binding the background and the Click command to members in the ViewModel. The first time the button is clicked it sets a flag and changes the background color. The next time the button is clicked, if the flag is set, the command returns without changing the background.
XAML:
<ToggleButton Background="{Binding MyBackground}" Command="{Binding OnClickCmd}"/>
ViewModel
public class ViewModel : INotifyPropertyChanged
{
public Brush MyBackground
{
get { return background_; }
set {
background_ = value;
PropertyChanged(this, new PropertyChangedEventArg("MyBackground");
}
}
public ICommand OnClickCmd
{
get {
return new DelegateCommand(()=>{ // DelegateCommand implements ICommand
if(!isBackgroundSet) {
background = Brushes.Red;
isBackgroundSet_ = true;
}
});
}
}
private Brush background_;
private bool isBackgroundSet_;
private event PropertyChangedEventHandler PropertyChagned;
}