I am attempting to create a LinkLabel control for WPF. Essentially, I'm going to create the LinkLabel from a TextBlock and handle MouseEnter, MouseLeave, and MouseLeftButtonUp events. In the back end I have a base class that has properties that you would expect to see with a LinkLabel. With most other clickable controls in WPF, there is a default MouseEnter animation where the control becomes Ice Blue. I would like to duplicate this behavior when the mouse cursor enters over the TextBlock. I'm not sure if I'm needing to derive from ButtonBase or something along those lines. I have a I am able to change the cursor to a hand, and handle the event for when the "LinkLabel" is clicked. If accessing this seemingly default color changing animations, then I just may have to resort to a simple foreground color swap without the smooth transition. If anyone has created a custom WPF LinkLabel before or has any advice into the matter your input would be much appreciated.
You can create the equivalent of WinForms' LinkLabel right now using a combination of TextBlock and HyperLink:
<TextBlock>Here is a <Hyperlink NavigateUri="http://example.com">link</Hyperlink></TextBlock>
You won't get the "ice blue" mouse-over effect, but you will get the hand cursor. I'm sure you can introduce your mouse-over effects using a simple style trigger.
The "NavigateUri" property works in navigation-style applications where the hyperlink is inside a Frame control. In a standard WPF application you'll want to handle the Hyperlink's Click event instead and use Process.Start to kick off a web browser with the correct URL.
I just created a style for a button and apply a style to a button whenever you want LinkLabel look. Click event of button is used to perform a function when the text is clicked.
<Style x:Key="LinkLabelButtonStyle" TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="CornflowerBlue"></Setter>
</Trigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="Transparent">
<ContentPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock TextDecorations="Underline" Text="{TemplateBinding Content}"></TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="DarkBlue"></Setter>
<Setter Property="MinWidth" Value="90"></Setter>
<Setter Property="HorizontalAlignment" Value="Left"></Setter>
<Setter Property="Padding" Value="5"></Setter>
<Setter Property="Margin" Value="5"></Setter>
<Setter Property="Cursor" Value="Hand"></Setter>
</Style>
You can place above style in the Window.Resources so you can use it in entire window.
Then apply the style to a button whenever you want LinkLabel look.
<Button Name="LinkLabelLookALikeButton" Content="Text goes here" Style="{StaticResource LinkLabelButtonStyle}" Click="Event_Goes_Here">
</Button>
Hope this helps!
Related
I have an Itemscontrol with an Itemscontrol with buttons. This makes a matrix with 64 buttons.
Each button is bound to a ViewModel. The buttons have an eclipse that has a color.
A button can have two states.
1) The ViewModel gives a Color for the eclipse in the button and then the button IsEnabled=true.
2) the button IsEnabled=false and the button is not clickable anymore.
I would to have a transparant background for number 2 (when the button is not enabled). I worked something out and got this (see code on Pastebin), but now my borders are gone and everything is transparant.
How can I get a border for each button that is visible all the time, so it is not restricted to number 1 and 2.
Here is my code. I put it on Pastebin to save space.
Pastebin: http://pastebin.com/4GHCW0y8
Thanks
There are a couple issues with your code:
You are setting the Background, BorderBrush and BorderThickness properties directly on your button instead of using setters in the style. Setting them this way overrides anything the style does, so you cannot see the effects of the style triggers. This is the line I am referring to:
<Button Style="{StaticResource MyButton2}" Command="{Binding PlaceStoneCommand}" Background="Transparent" BorderBrush="Black" BorderThickness="0.75" Width="30" Height="30">
Remove the Background, BorderBrush and BorderThickness properties from that line and make setters in the style instead. Also, note that you are setting the default to transparent, so even with this change, you are just switching between Transparent and Transparent when IsEnabled changes.
Your style is overriding the control template for the button and not using the BorderBrush or BorderThickness properties in the template, so setting those properties on the button is not going to have any effect. You probably want to setup template bindings for those properties on the Border defined in the template. So, you would end up with a style looking something like this:
<Style TargetType="{x:Type Button}" x:Key="MyButton2">
<!-- Put default values here, or remove these if you want to use the existing button defaults -->
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="1" />
</Trigger>
</Style.Triggers>
</Style>
See if those changes give you the desired result.
I'm assuming that this may be a style issue, but being new to wpf I'm not sure what I should be changing. I have built a user control containg various buttons (whose background colour I have set to be transparent). None the less when added to a form or other user control they exhibit a coloured background when disabled, or when run over by the mouse when enabled (see illustration below)
What do I need to do to remove the grey background on the button's disabled state, and also the blue background that appears on rollover when it is enabled. My aim is to try aand retain a clean and clear rendition of the button images.
Thanks
You would need to override the ControlTemplate of the Button controls using a Style. The following Style will apply to all Button controls, but you can specify a Key for the Style and use it on specific Button controls if you wish.
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="ButtonContent">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="ButtonContent"
Property="Background"
Value="Transparent"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Suppose I have n number of rectangles.
I want them to behave such that when I click on any rectangle it should be filled white and all other should be filled with black color.
I know that I can create a style. But while creating style I can tell the trigger that fill the rectangle with black color but how can I say that fill all the remaining rectangles with white color.
Can anyone suggest me?
I want just a small hint.
Don't make rectangles work like RadioButtons, make RadioButtons look like rectangles.I would suggest to use RadioButton instead and change template to make it look like rectangle. Then you can trigger change of background based on RadioButton.IsChecked property. This way RadioButton will take care of tick/untick operation and trigger background change in other RadioButtons in the same group.
<Style TargetType="{x:Type RadioButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Border BorderBrush="Black" BorderThickness="1" Background="Black" x:Name="PART_Border">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="PART_Border" Property="Background" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and use your RadioButton like this:
<RadioButton>
<RadioButton.Content>
<!-- content to be displayer inside border -->
</RadioButton.Content>
</RadioButton>
You've answered the question yourself. Take two radio buttons and try editing the template. Basically when you'll have the close look at the template you will find an ellipse with a dot whose visibility gets toggled off on mouse click
Instead of having the ellipse you can have a rectangle/border with some thickness and set its background color on mouse click
I change the background color of my TabItem conditionally in code behind. This works fine as long as no theme is set in the App.xaml. How can I change colors of a TabItem (in code) while keeping an application-wide theme?
Background:
I'm using a free WPF theme from Nukeation Reuxables. The theme is set in the Application.Resources section of my App.xaml:
<ResourceDictionary Source="/ReuxablesLegacy;component/Edge.xaml" />.
I'm trying to conditionally set the background color of a TabItem in code behind:
MyTabItem.Background = new SolidColorBrush(Colors.Gray);
The background color changes if I remove or comment out the App.xaml line that sets the theme. Why does the theme break my code? I'm changing the tab color (as data is loaded) to show which tabs contain data.
I'm aware that XAML and binding are typically used to change colors, but the solutions I've attempted seem overly complex. Here is my related StackOverflow question seeking an all XAML and binding solution. The answers given just raised more questions which I haven't found answers to.
Thanks in advance.
Edit:
The problem does not happen when changing the background of a button:
button1.Background = new SolidColorBrush(Colors.Red);
The button changes color as expected (while using an application-wide theme).
It REALLY depends on how the theme itself is implemented. If the theme was using TemplateBinding to bind to the background color of the tab to the theme's controls, then your code behind solution would work. That is probably why your button properly changes background colors in your example.
You'll probably have to dig deep into the tab's style xaml, and modify it there first for the codebehind solution to work.
If you look at the ControlTemplate of TabItem its Background property is bound to a internal resource it doesn't do TemplateBinding, I presume the theme has just given colors to it. For your code to work you have to restyle it.
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border
Name="Border"
Margin="0,0,-4,0"
Background="{TemplateBinding Background}"
BorderBrush="{StaticResource SolidBorderBrush}"
BorderThickness="1,1,1,1"
CornerRadius="2,12,0,0" >
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header"
Margin="12,2,12,2"
RecognizesAccessKey="True"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="{StaticResource DisabledBackgroundBrush}" />
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DisabledBorderBrush}" />
<Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I have made two changes to the normal ControlTemplate, you can do the same to your theme.xaml.
Changed Background="{StaticResource LightBrush}" to Background="{TemplateBinding Background}"
Removed Background setter in IsSelected = True trigger.
Unfortunately, this is a simple problem with no simple answer (that I have found so far). Taking a different path to satisfy users was my final solution.
Instead of attempting to change the TabItem Background color I simply change the TabItem Foreground color to Gray if NO data exists. I also add the word "Blank" like this: "Tab 1 Blank", "Tab 2 Blank", etc. This an effective solution to the original problem. I describe it in detail here.
What do I have?
I have a ListBox populated with items from an XML file. Given a DynamicResource for Style property and written trigger for IsSelected in ItemContainerStyle.
What do I want to do?
I want to keep the selected Item highlighted even after focus moved out of the ListBox.
What problem am I facing?
When I select an item the style specified in IsSelected trigger works. But, when I move the focus out of list box (press tab or click on some other control) the selected item loses its style. Is there any way so that I can retain the selected item style?
Thanks in advance!
The answer referenced will in some cases solve the problem, but is not ideal as it breaks when the control is disabled/readonly and it also overrides the color schemes, rather than taking advantage of them. My suggestion is to add the following in the ListBox tags:
<ListBox....>
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border Name="Border" Padding="2" SnapsToDevicePixels="true">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Border" Property="Background"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
</ListBox>
What this will do is set the Highlight background color on the list box item whenever it is selected (regardless of the control state).
My answer is based on help from the answers already given to these answers, along with the following blog: http://blogs.vbcity.com/xtab/archive/2009/06/29/9344.aspx
If you're only setting the background color, try replacing ControlBrush for the ListBox, as per this answer.