wpf ListView - disable header mouse over effect - wpf

I have a simple 1 column ListView and I need to disable the mouse over effect for the GridViewColumnHeader.
I tried grabbing the style from here: http://msdn.microsoft.com/en-us/library/ms788747.aspx
However that gave my header a purple gradient so I guess it was the wrong style. I do notice it has a
<VisualState x:Name="MouseOver">
But I have no idea how to remove that without finding and including the correct GridViewColumnHeader style and then removing it.
I tried the following, but it doesn't do anything (The VisualState overrides?) and wouldn't work anyway as setting the background to null wouldn't be what I want.
<Style x:Key="hcs" TargetType="{x:Type GridViewColumnHeader}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>

The problem is, like you said yourself, in MouseOver visual state and its Storyboard. I think it`s better to get rid from redundant functionality than try to override it later. So we basically just need the same style but without that storyboard. For bare minimum we need to have following things (can be found on MSDN via the link you provided):
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Style x:Key="GridViewColumnHeaderGripper"
TargetType="Thumb">
<!-- Full GridViewColumnHeaderGripper style here -->
</Style>
<Style TargetType="GridViewColumnHeader">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GridViewColumnHeader">
<!-- Standard template but with redundant Storyboard removed -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The last Style doesn`t have a key so it applies to all GridViewColumnHeader on page \ application (depends on where it is defined). Or you can set the key and use it only in specific grids.
That`s bare minimum so for more customizable approach it may be better to copy other parts of default style too.

Related

Change a Style based on Visual State

"Blend makes it simple to setup Visual States based on say minWindowWidth. But it would be very nice to have state-based Styles defined for TextBlock elements, say with tag="header", tag="body", and have the Setter change the Style automatically."
Maybe I wasn't explicit enough in my initial question, let me rephrase this.
I am resizing my application window from say Landscape to Portrait. My VisualStateManager has setters which adjust the page properties based on the new minimum width.
I have multiple TextBlocks (header,body, etc) and other controls with .Text (ToggleSwitch), that I want to automatically adjust FontSize based on the new width.
Aside from manually setting every single control by name in all the states, is there a way to have the VisualStateManager do it automatically for each 'type' of Text(body/header/etc)? My work around at the moment is to DataBind a Style for every .Text control and have the ViewModel do all the scaling. That works, but this is really something Blend is made for, right? So I must be missing the obvious way everyone is using.
Thanks for all the good comments so far.
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="PhonePortrait">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="{StaticResource NarrowMinWidth}"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="SwitchStackPanel.(StackPanel.Orientation)" Value="Vertical"/>
<!-- Setter to change all Body textblocks to FontSize=8-->
<!-- Setter to change all Header textblocks to FontSize=10-->
<!-- Setter to change all ToggleSwitch.Text to FontSize=8-->
<!-- etc..-->
You could use a global style. That utilizes triggers based on the Tag.
<Style TargetType="{x:Type TextBlock}">
<!--Default Setters Here-->
<Setter Property="Background" Value="White"/>
<Style.Triggers>
<Trigger Property="Tag" Value="body">
<Setter Property="Background" Value="Gray"/>
<!--Insert desired state setters here-->
</Trigger>
<Trigger Property="Tag" Value="header">
<Setter Property="Background" Value="DarkGray"/>
<!--Insert desired state setters here-->
</Trigger>
</Style.Triggers>
</Style>
You can then have a default state, and Triggered setters than only affect a Textblock when an applicable tag is attached.
If you already have other styles or want to have a selection process, you may want to add a key and then use BasedOn within the style.

How to override the enabled /disabled look on a button in wpf

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>

Implicity style for BarDataPoint is not applied

I am currently working on creating a theme for charts.
Beside other things, I want to make the bars in BarSeries have a flat look(without borders).
I want to make it to work with implicit styling so I added a Style to BarDataPoint(without a Key because it needs to work by implicit styling) but it is not applied.
Any idea why is it is not applied?
Is it because of DataPointStyle style from Palette which is applied instead?
What I am trying to do is to change the look of the BarDataPoint but still have the colors from the palette applied. And also try to make this work by pure XAML(if possible).
In order to make this work, the only way I see is by changing DataPointStyle(in each ResourceDictionary from Chart.Palette) to have TargetType set to BarDataPoint and Template set to my template implementation:
<toolkit:Chart.Palette>
<toolkit:ResourceDictionaryCollection>
<ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="toolkit:BarDataPoint" BasedOn="{StaticResource BarDataPointStyle}">
<Setter Property="Background" Value="Yellow" />
<Setter Property="BorderBrush" Value="Black" />
</Style>
</ResourceDictionary>
<ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="toolkit:BarDataPoint" BasedOn="{StaticResource BarDataPointStyle}">
<Setter Property="Background" Value="Red" />
<Setter Property="BorderBrush" Value="Black" />
</Style>
</ResourceDictionary>
</toolkit:ResourceDictionaryCollection>
</toolkit:Chart.Palette>
But since this is for implicit style for Chart control, how would that work if I have a Char control with a different type of series, for example a Chart with ColumnSeries? I don't think the DataPointStyle will work in this case because it is targeting the BarDataPoint type(I suppose the app will crash).
Am I forced to create different Chart styles with different keys(each style having DataPointStyle changed to target different control template)?
But then, how will that work for a Chart control with several different series?
I also tried to use an implicit style for toolkit:BarDataPoint in the palette's resource dictionary like this, but without success:
<Setter Property="Palette">
<Setter.Value>
<toolkit:ResourceDictionaryCollection>
<ResourceDictionary>
<SolidColorBrush x:Key="Background"
Color="#FFCA294D" />
<Style TargetType="toolkit:BarDataPoint">
<Setter Property="Template"
Value="{StaticResource BarDataPointTemplate}" />
<Setter Property="Background"
Value="{StaticResource Background}" />
</Style>
I tried to look to themes like JetPack but they don't seem to do what I want.
Thanks!
sorry for late update.
check this solution. may help others too
Silverlight 4: Chart Toolkit Color Set

Changing between named styles

A few months ago in a C# application I began using a ListBox as a container for some UserPanels. When a panel was selected it was highlighted, just like any listbox item. I found the following XAML I was able to add to give all items a transparent background (Not sure where I originally found this or I'd link it)
<Application.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="border" Background="Transparent">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="border" Property="Background">
<Setter.Value>Transparent</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
This worked fine but now I need to sometimes have a background color instead of a transparent background. There is only 1 listbox and the contents change so I want to programatically change the style in the codebehind.
I found examples on changing the style in code but I wasn't able to create two of this same style. I gave it a x:name="transparentListbox", copied it, and gave the other one x:name="normalListbox" with a background of Blue, but I get an XML parse exception having two style elements, possibly because they're both generically trying to modify every listbox.
How can I have two named styles that accomplish the same thing (modifying the background when an item is selected) that I can switch between in code as needed?
Edit:
In every case my listbox is used to store UserPanels. I add them to the listbox using lstPanels.Items.Add(p) where p is an instance of a class derived from UserPanel.
When I first made the app there were multiple windows so the windows that required transparency had this style, and those that required selecting items did not. Managing multiple windows became cumbersome so it was re-factored into a single window and the listbox would be cleared and loaded with different types of panels when the mode changed. Some still required transparent backgrounds, but now some did not.
Programatically assigning a named style to the Listbox as a whole, when the mode changes, would be okay. Assigning a style to every ListBoxItem would involve updates to a lot of code as that functionality is spread out.
Perhaps the solution would be to maintain a single style but have the background property be bound to a varaible, if that is at all possible?
I have always created the style in my UserControl.Resources section.
In your case:
<Style x:Key="ListBoxStyle1" TargetType="MyDerivedListBoxItem">
...
<Style x:Key="ListBoxStyle2" TargetType="MyDerivedListBoxItem">
...
and in the code behind I have set the styles this way.
If Not MyListBox.ItemContainerStyle.Equals(CType(Resources("ListBoxStyle1"), Style)) Then
MyListBox.ItemContainerStyle= CType(Resources("ListBoxStyle1"), Style)
I wouldn't mess with trying to modify styles in your code. It may be feasible and even work, but that seems like a world of pain to me. One idea that might help is that you could inherit from ListBoxItem, defining your own control. You could then put a dependency property on that inheritor like UseAlternateBackgroundColor of type bool or something.
Then, you'd modify your style:
<Style TargetType="MyDerivedListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MyDerivedListBoxItem}">
<Border x:Name="border" Background="Transparent">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="border" Property="Background">
<Setter.Value>Transparent</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="UseAlternateBackgroundColor" Value="true">
<Setter TargetName="border" Property="Background">
<Setter.Value>Black</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Generally speaking, I personally try to avoid dealing with layout and visual style considerations in code as much as possible.
You need to set different x:Key directives, if the styles are resources the Name is pretty useless anyway. If you do not set a key the TargetType is used as the key instead which causes a collision. To apply one of the styles in code you can call FindResource with the respective key.

How to make WPF DataGrid Column Header transparent

I am trying to make the column header of my WPF Datagrid to be transparent.
I am able to set it to a color without problem, but I can't have it transparent. Here is what I tried:
<Style x:Key="DatagridColumnHeaderStyle" TargetType="{x:Type tk:DataGridColumnHeader}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="#C2C4C6" />
</Style>
<Style x:Key="DashboardGridStyle" TargetType="{x:Type tk:DataGrid}">
<Setter Property="ColumnHeaderStyle" Value="{StaticResource DatagridColumnHeaderStyle}" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="RowBackground" Value="Transparent" />
</Style>
<tk:DataGrid Style="{StaticResource DashboardGridStyle}" >
...
</tk:DataGrid>
With this code, it seems to take the default brush.
What am I missing?
I used Snoop to take a look at what was happening. It seems that another DataGridColumnHeader is always created behind the one you can modify, and it's not affected by changes on styles. When you set a transparent background, in fact is being correctly applied, so what you see is that ghost header behind (which has the usual grey background).
If you apply a coloured background and play with Opacity, you will see how the two colours are mixed. I don't know if this can be solved.
With the answer from Natxo (thanks!), I was able to find a solution. And it is a simple one too!
Knowing that there was another DataGridColumnHeader behind the one we can modify through the ColumnHeaderStyle, I just had to set a style that will affect all DataGridColumnHeader:
<Style TargetType="{x:Type tk:DataGridColumnHeader}">
<Setter Property="Background" Value="Transparent" />
</Style>

Resources