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

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.

Related

Devexpress- Background and grid lines in a gridcontrol

I have run into a few issues with gridcontrol.
I have to style and format a grid column with padding,colors,fonts and hover effects.
<Style x:Key="SelectedRowStyle" TargetType="{x:Type dxg:RowControl}">
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontFamily" Value="pack://application:,,,/PA.Tos.UI;component/ResourceDictionaries/#Brandon Grotesque Black" />
<Setter Property="FontSize" Value="12" />
<Setter Property="FontWeight" Value="Regular" />
<Style.Triggers>
<DataTrigger Binding="{Binding
ElementName=GroupCodeListView,Path=DataContext.SelectedGroupCode.Deleted,
UpdateSourceTrigger=PropertyChanged}" Value="true">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="Black" />
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource HoverRowBorderColor}" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
<Trigger Property="dxg:GridViewBase.IsFocusedRow" Value="True">
<Setter Property="Background" Value="{StaticResource HoverRowBorderColor}" />
<Setter Property="BorderBrush" Value="{StaticResource HoverStrokeColor}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="CustomCellStyle" BasedOn="{StaticResource {dxgt:GridRowThemeKey
ResourceKey=LightweightCellStyle}}" TargetType="{x:Type dxg:LightweightCellEditor}">
<Setter Property="MaxHeight" Value="25"/>
<Setter Property="MinHeight" Value="25"/>
<Style.Triggers>
</Style.Triggers>
In response to a mouse hover or row selection, i have to set the border blue across all grid lines. Only the bottom grid line is blue as of
now from the above. Code applicable to cellcontent presenter won't be possible here.
In response to a trash icon clicked, i have to display light red background for the particular row.
I bind (viewmodel property)SelectedGroupCode.Deleted=true to the background.The binding is shown in the code.
but all rows are painted red except the row in question.
The grid lines width has to be set. i have managed to set it for the horizontal lines only using gridrowthemekey_rowcontrolcontainertemplate.
I assure you i have read through some previous threads but its taking too much time for a scrum sprint.
What is missing?
If you want to change the cell style in response to a mouse hover then you can use RelativeSource markup extension in DataTrigger's binding. If you want to check whether the row is focused, then you can use RowData.IsFocused property.
Here is example:
<Style x:Key="CustomCellStyle" TargetType="{x:Type dxg:LightweightCellEditor}" BasedOn="{StaticResource {dxgt:GridRowThemeKey ResourceKey=LightweightCellStyle}}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type dxg:RowControl}}}" Value="True">
<Setter Property="BorderBrush" Value="Blue" />
</DataTrigger>
<DataTrigger Binding="{Binding RowData.IsFocused}" Value="true">
<Setter Property="BorderBrush" Value="Blue" />
</DataTrigger>
</Style.Triggers>
</Style>
For displaying custom style for particular row I suggest you to use Conditional Formatting.
Here is example:
<dxg:GridControl ...>
...
<dxg:GridControl.View>
<dxg:TableView>
<dxg:TableView.FormatConditions>
<dxg:FormatCondition Expression="[Deleted]" FieldName="Profit">
<dxc:Format Foreground="Red"/>
</dxg:FormatCondition>
</dxg:TableView.FormatConditions>
</dxg:TableView>
</dxg:GridControl.View>
</dxg:GridControl>

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>

Change background on WPF Listview item when it's selected

I have a WPF Listview, and I have overridden the ListView.ItemTemplate to change the background color of the items on the ListViewItem.IsMouseOver event like so:
<AlternationConverter x:Key="BackgroundConverter">
<SolidColorBrush>White</SolidColorBrush>
<SolidColorBrush>
<SolidColorBrush.Color>
<Color A="242" R="242" G="242" B="242" />
</SolidColorBrush.Color>
</SolidColorBrush>
</AlternationConverter>
<Style x:Key="alternatingWithBinding" TargetType="{x:Type ListViewItem}">
<Setter Property="Height" Value="31"/>
<Setter Property="Background"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(ItemsControl.AlternationIndex),
Converter={StaticResource BackgroundConverter}}"/>
<Style.Triggers>
<Trigger Property="ListViewItem.IsSelected" Value="True">
<Setter Property="ListViewItem.Background" Value="Yellow" />
</Trigger>
<Trigger Property="ListBoxItem.IsMouseOver" Value="True">
<Setter Property="ListBoxItem.Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
What I'm trying to achieve is to have a different color when hovered over the already selected item (which is yellow). So on all the items it will be a Blue hover-over, and on the selected Yellow item, it'll be green.
I tried the below attempt, using MultiTrigger, but that didn't do the trick:
<Style x:Key="alternatingWithBinding" TargetType="{x:Type ListViewItem}">
<Setter Property="Height" Value="31"/>
<Setter Property="Background"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(ItemsControl.AlternationIndex),
Converter={StaticResource BackgroundConverter}}"/>
<Style.Triggers>
<Trigger Property="ListViewItem.IsSelected" Value="True">
<Setter Property="ListViewItem.Background" Value="Yellow" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ListBoxItem.IsMouseOver" Value="True"/>
<Condition Property="ListBoxItem.IsSelected" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="ListBoxItem.Background" Value="Green" />
</MultiTrigger>
<Trigger Property="ListBoxItem.IsMouseOver" Value="True">
<Setter Property="ListBoxItem.Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
Any ideas?
Thanks.
Are the triggers are applied in order? It might work if you move the MultiTrigger to the bottom, then it will apply after the IsMouseOver Trigger.

WPF DataGridRow - Considering multiple conditions in Triggers

Working with a WPF datagrid, I need to comply with these requeriments:
Change row background when IsMouseOver.
Change row background to red when a critical property is met.
Change row background to violet when a row is selected, but not critical.
Change row background to dark red when a row is selected and critical.
I cannot met the last condition so far. My code right now is:
<Style x:Key="GridRow" TargetType="DataGridRow">
<Setter Property="FontSize" Value="10" />
<Setter Property="Foreground" Value="#000000" />
<Setter Property="Background" Value="#E5E5E5" />
<Setter Property="Height" Value="24" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#F5F5F5" />
</Trigger>
<DataTrigger Binding="{Binding IsStatusCritical}" Value="True">
<Setter Property="Background" Value="Red"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="#660066" />
</Trigger>
</Style.Triggers>
</Style>
You can solve this using MultiDataTriggers. Just make sure that you place them in the correct order, as I recall, the last trigger that meets all criteria takes precedence.

WPF datagrid template

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.

Resources