WPF datagrid template - wpf

I want to make a WPF datagrid look similar to the HTML grid in the following picture:
http://img443.imageshack.us/img443/2563/saltoftheearth.jpg
Does anyone know an easy way to do this ?
Regards,
S.

I managed to make it look like this ( http://img697.imageshack.us/img697/9417/failedwpfdatagridstylin.jpg ) using the following code in a resource file. However, it still does not look like the HTML counterpart ( http://img443.imageshack.us/img443/2563/saltoftheearth.jpg )....It has to many borders .... Any ideas on how to make this WPF datagrid look nicer ?
Value="12" />
<Style x:Key="DataGridCellStyle" TargetType="{x:Type my:DataGridCell}" >
<Setter Property="FontFamily"
Value="Tahoma" />
<Setter Property="FontSize"
Value="12" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Transparent" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="DataGridStyle"
TargetType="{x:Type my:DataGrid}" >
<Setter Property="RowHeaderWidth"
Value="0" />
<Setter Property="HorizontalAlignment"
Value="Left" />
<Setter Property="SelectionUnit"
Value="Cell" />
<Setter Property="SelectionMode"
Value="Single" />
<Setter Property="AutoGenerateColumns"
Value="false" />
<Setter Property="CanUserAddRows"
Value="False" />
<Setter Property="CanUserDeleteRows"
Value="False" />
<Setter Property="CanUserResizeRows"
Value="False" />
<Setter Property="CanUserResizeColumns"
Value="False" />
<Setter Property="CanUserSortColumns"
Value="True" />
<Setter Property="CanUserReorderColumns"
Value="False" />
<Setter Property="IsReadOnly"
Value="True" />
</Style>

You can take a look here, at C# Corner, there are lots of useful tutorials there, and Im pretty sure you can find it, like this one.

Related

Style inherittance between different target types

I don't know if I am just not understanding right. I am trying to make 2 different button styles for my application: BlueOnWhiteButton and WhiteOnBlueButton.
Both these buttons should be identical, but the foreground and backgrounds are reversed. So far, oh so simple.
Here is the catch: I need my buttons to have rounded corners. This simple requirement doesn't seem to be so simple after all. Also there maybe a little border of a different color on both versions.
Using some things I found on google and stack, I came up with this style for the first one, and it looked promising:
<Style x:Key="WhiteOnBlueButton"
TargetType="Button">
<Setter Property="Background" Value="{StaticResource MainBlue}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontWeight" Value="bold" />
<Style.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="BorderBrush" Value="{StaticResource LightBlue}" />
</Style>
</Style.Resources>
</Style>
So far so good, my button looks how I want it. But then, when I try to make a second style underneath, I get an error at runtime because of the Style.Resources redefine. I'll save you the code block, figure the same with a different name and reversed colors.
I am trying to keep the use of the style as simple as possible, I have tried versions with templates, but it made the style a lot more complicated, and I even lost the button text...
What I would like to have is something like this:
<Style x:Key="RoundedButtonCornersNoBorder" TargetType="Border">
<Setter Property="CornerRadius" Value="4"/>
<Setter Property="BorderThickness" Value="0" />
</Style>
<Style x:Key="RoundedButtonCorners" TargetType="Border">
<Setter Property="CornerRadius" Value="4"/>
<Setter Property="BorderBrush" Value="{StaticResource LightBlue}" />
<Setter Property="BorderThickness" Value="2" />
</Style>
<Style x:Key="WhiteOnBlueButton"
TargetType="Button">
<Setter Property="Background" Value="{StaticResource MainBlue}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontWeight" Value="bold" />
<!-- Somehow tell the borders should be taken from the style RoundedButtonCornersNoBorder-->
</Style>
<Style x:Key="BlueOnWhiteButton"
TargetType="Button">
<Setter Property="Background" Value="White" />
<Setter Property="Foreground" Value="{StaticResource MainBlue}" />
<Setter Property="FontWeight" Value="bold" />
<!-- Somehow tell the borders should be taken from the style RoundedButtonCorners-->
</Style>
Is there any way to code that without writing 300 lines of incomprehensible code?
The final goal is to apply the style by simply doing:
<Button
Style="{DynamicResource WhiteOnBlueButton}"
Content="CLICK ME!" />
You could move the Border Style in the Resources of a common base Style and derive the final Button Styles from the common base Style by means of the BasedOn property.
Do not set the BorderBrush in the Border Style, but either in the base or final Button Styles. The Border in the Button Template will pick it up from the Button via a TemplateBinding.
<Style x:Key="RoundedButtonCorners" TargetType="Button">
<Style.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"/>
<Setter Property="BorderThickness" Value="2"/>
</Style>
</Style.Resources>
<Setter Property="BorderBrush" Value="{StaticResource LightBlue}"/>
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Style x:Key="WhiteOnBlueButton" TargetType="Button"
BasedOn="{StaticResource RoundedButtonCorners}">
<Setter Property="Background" Value="{StaticResource MainBlue}"/>
<Setter Property="Foreground" Value="White"/>
</Style>
<Style x:Key="BlueOnWhiteButton" TargetType="Button"
BasedOn="{StaticResource RoundedButtonCorners}">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="{StaticResource MainBlue}"/>
</Style>
Turns out we have a library that has a button exposing the border directly.
Final styles look like this:
<Style x:Key="WhiteOnBlueButton" TargetType="telerik:RadButton">
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="{StaticResource MainBlue}" />
<Setter Property="FontWeight" Value="bold" />
<Setter Property="CornerRadius" Value="5" />
<Setter Property="BorderBrush" Value="{StaticResource LightBlue}" />
<Setter Property="BorderThickness" Value="0" />
</Style>
<Style x:Key="BlueOnWhiteButton" TargetType="telerik:RadButton">
<Setter Property="Foreground" Value="{StaticResource MainBlue}" />
<Setter Property="Background" Value="White" />
<Setter Property="FontWeight" Value="bold" />
<Setter Property="CornerRadius" Value="5" />
<Setter Property="BorderBrush" Value="{StaticResource LightBlue}" />
<Setter Property="BorderThickness" Value="0" />
</Style>
And then building my button:
<telerik:RadButton
x:Name="xamlFullTextSearchButton"
Style="{StaticResource BlueOnWhiteButton}"
Grid.Column="2"
Grid.Row="0"
Content="CLICK ME"
CornerRadius="4"/>
With this, I don't even loose the clicking animation! It's perfect for what I need!

WPF StaticResource: An item with the same key has already been added

I have a resource dictionary containing the following:
<SolidColorBrush x:Key="RowAlt"
Color="Gray" />
<Style x:Key="MainTreeRowStyle"
TargetType="{x:Type dxg:RowControl}">
<Setter Property="Foreground"
Value="White" />
<Setter Property="ShowHorizontalLine"
Value="False" />
<Setter Property="ShowVerticalLines"
Value="False" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding AlternateRow}"
Value="False" />
</MultiDataTrigger.Conditions>
<Setter Property="Background"
Value="Black" />
</MultiDataTrigger>
<Trigger Property="dxg:GridViewBase.IsFocusedRow"
Value="True">
<Setter Property="Background"
Value="{StaticResource RowAlt}" />
</Trigger>
</Style.Triggers>
</Style>
The above is throwing an exception
" An item with the same key has already been added."
If i replace
<Setter Property="Background"
Value="{StaticResource RowAlt}" />
with
<Setter Property="Background"
Value="{DynamicResource RowAlt}" />
No exception is thrown. Why is this?
The difference between StaticResource and DynamicResource lies in how the resources are retrieved by the referencing elements. StaticResource are retrieved only once by the referencing element and used for entire life of the resource. On the other hand, DynamicResource are acquired every time the referenced object is used.

DatagridRow's mouseover not working properly

I have the following styles for my datagrid :
<Style x:Key="StyleDataGrid" TargetType="{x:Type DataGrid}">
<Setter Property="SelectionMode" Value="Single" />
<Setter Property="SelectionUnit" Value="FullRow" />
<Setter Property="CanUserAddRows" Value="False" />
<Setter Property="AutoGenerateColumns" Value="False" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="CanUserResizeColumns" Value="True" />
<Setter Property="GridLinesVisibility" Value="Horizontal" />
<Setter Property="HorizontalGridLinesBrush" Value="Black" />
<Setter Property="CanUserReorderColumns" Value="False" />
<Setter Property="HeadersVisibility" Value="Column" />
<Setter Property="CanUserDeleteRows" Value="False" />
<Setter Property="Padding" Value="8"/>
</Style>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Padding" Value="5" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="FontSize" Value="14" />
<Setter Property="FontFamily" Value="Helvetica" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border Padding="{TemplateBinding Padding}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<ContentPresenter.ContentTemplate>
<DataTemplate>
<TextBlock Background="Transparent" Name="text" TextTrimming="CharacterEllipsis"
Height="auto" Width="auto" Text="{Binding Text}"/>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<!--<Setter Property="ToolTip" Value="{Binding Content.Text, RelativeSource={RelativeSource Self}}"/>-->
<Setter Property="Background" Value="Orange"/>
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Margin" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Background" Value="{StaticResource CouleurFond}" />
<Setter Property="Foreground" Value="{StaticResource ResourceKey=CouleurTexte}" />
<Setter Property="Padding" Value="5"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Orange"/>
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
But the mouseOver event on my DataGridRow doesn't work. When My mouse is over a row, the row 's Background is red but the text's foreground remains Black on all my columns excepted the cell under my mouse where the text became white as expected.
But I'd like to have all my line's foreground white when my mouse is over a row. What is wrong with my styles ?
Thank you
The trick was to add these lines to manage the mouse over event of my DataGridCell:
<DataTrigger Binding="{Binding Path=IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Value="True">
<Setter Property="Background" Value="{StaticResource ResourceKey=CouleurBoutonHover}"/>
<Setter Property="Foreground" Value="{StaticResource ResourceKey=CouleurTexteBoutonHover}" />
</DataTrigger>
and it was working :)
If you comment out your other Styles temporarily, you'll see that actually, your DataGridRow Style works just fine... the Background of the selected DataGridRow is Orange as you required:
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="Margin" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Background" Value="{StaticResource CouleurFond}" />
<Setter Property="Foreground" Value="{StaticResource ResourceKey=CouleurTexte}" />
<Setter Property="Padding" Value="5"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Orange"/>
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style
Therefore, you need to set your other Styles more carefully. Add them part by part and keep running the program occasionally to check that your problem hasn't reappeared and if it has, just undo the last edit or two, as that was what was causing your problem.
UPDATE >>>
Please read my last paragraph again:
you need to set your other Styles more carefully. Add them part by part and keep running the program occasionally to check that your problem hasn't reappeared and if it has, just undo the last edit or two, as that was what was causing your problem.
Add them part by part does not mean add the whole DataGridCell Style back in one go as you clearly have done. If you had added the setters back into the DataGridCell Style part by part then you would have noticed which setter is causing the problem for you.

Style as resources for custom user control

I am trying to modify Extended WPF toolkit wizard control which is a Custom control it has a default style in generic.xaml file but now I want to modify it so based on Wizard type it changes its style completely
<Style TargetType="{x:Type local:Wizard}">
<Style.Triggers>
<Trigger Property="WizardType" Value="Normal">
<Setter Property="Style" Value="{StaticResource StandartWizardTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
this is how I have its generic.xaml modified but StandardWizardTemplate is not resolved during insistence
<Style x:Key="StandartWizardTemplate" TargetType="{x:Type local:Wizard}">
<Setter Property="Background" Value="#F0F0F0" />
<Setter Property="BorderBrush" Value="#A0A0A0" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
//Content of default template before modification
</Setter>
</Style>
Same file contains another style definition which changes Page ControlTemplate Based on trigger so I though I will be able to do the same thing for Wizard
<Style TargetType="{x:Type local:WizardPage}">
<Style.Triggers>
<Trigger Property="PageType" Value="Blank">
<Setter Property="Background" Value="#FFF0F0F0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template" Value="{StaticResource BlankWizardPageTemplate}" />
</Trigger>
<Trigger Property="PageType" Value="Exterior">
<Setter Property="Background" Value="#FFFFFF" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="ExteriorPanelBackground" Value="#E3EFFF" />
<Setter Property="Template" Value="{StaticResource ExteriorWizardPageTemplate}" />
</Trigger>
<Trigger Property="PageType" Value="Interior">
<Setter Property="Background" Value="#FFF0F0F0" />
<Setter Property="BorderBrush" Value="{x:Static SystemColors.ActiveBorderBrush}" />
<Setter Property="BorderThickness" Value="0,1,0,0" />
<Setter Property="HeaderBackground" Value="#FFFFFF" />
<Setter Property="Template" Value="{StaticResource InteriorWizardPageTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
Can anyone provide me with the right Styling implementation so that my Wizard Custom Control can be styled in the same way as Page does?
OK I found solution for this problem, All i had to do was to create new ResourceDictionary and declare Wizard ControlTemplate with key set. After that inside Generic.xaml I created Marge Resource Dictionary and included all separate Control template dictionaries inside
After All my generic.xaml looks in this way now.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Converters="clr-namespace:CuratioCMS.Client.UI.Core.Converters"
xmlns:local="clr-namespace:CuratioCMS.Client.UI.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="./NormalWizardStyle.xaml" />
<ResourceDictionary Source="./StepBased.xaml" />
<ResourceDictionary Source="./MixedModeWizard.xaml" />
</ResourceDictionary.MergedDictionaries>
<Converters:WizardPageButtonVisibilityConverter x:Key="WizardPageButtonVisibilityConverter" />
<Style TargetType="{x:Type local:Wizard}">
<Style.Triggers>
<Trigger Property="WizardType" Value="Normal">
<Setter Property="Template" Value="{StaticResource NormalModeWizardTemplate}" />
</Trigger>
<Trigger Property="WizardType" Value="StepWisivle">
<Setter Property="Template" Value="{StaticResource StepModeWizardTemplate}" />
</Trigger>
<Trigger Property="WizardType" Value="MixedMode">
<Setter Property="Template" Value="{StaticResource MixedModeWizardTemplate}" />
</Trigger>
</Style.Triggers>
<Setter Property="Background" Value="#F0F0F0" />
<Setter Property="BorderBrush" Value="#A0A0A0" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

Creating a drop shadow style in XAML

I’m struggling a little bit with some XAML syntax I hope someone can advise on. I want to create an “Effect” type style resource which contains a DropShadowEffect definition which can be reused rather than always manually setting the properties. Here’s what I have:
<Style TargetType="DropShadowEffect" x:Name="DropShadowEffectStyle">
<Setter Property="BlurRadius" Value="5" />
<Setter Property="Direction" Value="315" />
<Setter Property="ShadowDepth" Value="2" />
<Setter Property="Opacity" Value="0.5" />
</Style>
<Style TargetType="TextBlock" x:Name="PageTabLabelStyle">
<Setter Property="FontSize" Value="16" />
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="Foreground" Value="#EFEFEF" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="0, 10, 0, 10" />
<Setter Property="Effect" Value="{StaticResource DropShadowEffectStyle}" />
</Style>
This fails dismally each time it runs so I’m obviously missing something. I think it’s around the “Effect” property of the text block style expecting an “Effect” type rather than a “DopShadowEffect” type. Any ideas?
You cannot "style" an effect, because Style is a property of Control and an effect is not a Control.
What you really want to do is put the effect itself into the resource dictionary and use a StaticResource reference to point to it. Something like:
<UserControl.Resources>
<DropShadowEffect x:Key="dropShadow" BlurRadius="25" Direction="315" />
<Style TargetType="TextBlock" x:Name="PageTabLabelStyle">
<Setter Property="FontSize" Value="16" />
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="Foreground" Value="#EFEFEF" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Margin" Value="0, 10, 0, 10" />
<Setter Property="Effect" Value="{StaticResource dropShadow}" />
</Style>
</UserControl.Resources>

Resources