Applying styles dynamically for the TreeViewItems inside usercontrol in WPF - c#

I want to apply styles to all RadTreeViewItems in usercontrol from my MainWindow.xaml. I have style related to RadTreeViewItem in resource dictionary and when I try to apply it to usercontrol it is throwing exception.
TreeItemStyle
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
>
<Style x:Key="GenericTreeItemStyle" TargetType="{x:Type telerik:RadTreeViewItem}" BasedOn="{StaticResource {x:Type telerik:RadTreeViewItem}}" >
<Setter Property="IsSelected" Value="{Binding IsSelected,Mode=TwoWay}" />
<Setter Property="IsExpanded" Value="{Binding IsExpanded,Mode=TwoWay}" />
<Setter Property="IsInEditMode" Value="{Binding IsInEditMode,Mode=TwoWay}" />
<Setter Property="FontWeight" Value="{Binding NodeFontLook,Mode=OneWay}"/>
<Setter Property="FontStyle" Value="{Binding NodeFontStyle,Mode=OneWay}"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
Usage in MainWindow.xaml
<UC:TreeUserControl Name="RepositoryTree" Style="{StaticResource GenericTreeItemStyle}"/>
It is giving exception
"'RadTreeViewItem' TargetType does not match type of element 'TreeUserControl'."
How to apply styles to inner controls of UserControl from MainWindow.xaml?

Related

Why is my button style not applied when declared in the resources of another style? [duplicate]

This question already has answers here:
How do you change Background for a Button MouseOver in WPF?
(6 answers)
Closed last month.
I don't understand why this doesn't change the Background and Foreground while hovering the Button. It changes the CornerRadius of the Border tho.
ButtonStyle.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="Button" x:Key="RoundedCorners">
<Style.Resources>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"/>
</Style>
</Style.Resources>
</Style>
</ResourceDictionary>
LoginView.xaml
<Button Height="50"
Width="200"
Style="{StaticResource RoundedCorners}">
LOGIN
</Button>
In WPF, an explicit Style set locally through Style={StaticResource StyleKey} takes precedence over an implicit style matched through a TargetType, as detailed here.
Hence, only the outer Style is applied to your Button because it's given a key and epxlicitly set.
To fix it, you should meger the inner Style into the keyed Style like this:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="Button" x:Key="RoundedCorners">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="Foreground" Value="Green"/>
</Trigger>
</Style.Triggers>
<Style.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"/>
</Style>
</Style.Resources>
</Style>
</ResourceDictionary>
This will properly change the Foreground when you hover it. The Background will still not change, but that's an entire different problem.

Complementing Application.Resources.Style with UserControl.Style for DataRow in DataGrid

I have a global style used in all the applications DataGrid's, defined in the Application.Resources:
<Application.Resources>
<ResourceDictionary>
<Style x:Key="StyleDataGridRow" TargetType="{x:Type DataGridRow}">
<Setter Property="VerticalAlignment" Value="Center" />
<Style.Triggers>
<Trigger Property="DataGrid.IsSelected" Value="True">
<Setter Property="DataGrid.BorderBrush" Value="{DynamicResource SecondaryHueMidBrush}" />
<Setter Property="DataGrid.BorderThickness" Value="1" />
<Setter Property="Background" Value="{DynamicResource PrimaryHueLightBrush}" />
</Trigger>
<Trigger Property="DataGrid.IsSelected" Value="False">
<Setter Property="DataGrid.BorderBrush" Value="{DynamicResource SecondaryHueMidBrush}" />
<Setter Property="DataGrid.BorderThickness" Value="1" />
</Trigger>
</Style.Triggers>
</Style>
</Application:Resources>
In my UserControl I would like to add a style - keeping the global style - to highlight a row depending on an item used in this DataGrid. I could define this style in the UserControl's resources:
<UserControl.Resources>
<ResourceDictionary>
<Style x:Key="priceMissing" TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=priceIsMissing}" Value="true">
<Setter Property="Background" Value="LightSalmon" />
</DataTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</UserControl.Resources>
The global style is applied to the UserControl's DataGrid like this:
<DataGrid x:Name="dgCalculatedServices"
Margin="20,0,0,0"
CellStyle="{StaticResource StyleDataGridCell}"
DataContext="{Binding}"
ItemsSource="{Binding calculationServiceCodes.collection}"
Style="{StaticResource StyleDataGrid}"
RowStyle="{StaticResource StyleDataGridRow}">
Does anyone know a way to use the global style on a DataGrid and complement it with the local style?
That is what the BasedOn property is for.
Styles can be based on other styles through this property. When you use this property, the new style will inherit the values of the original style that are not explicitly redefined in the new style.
Specify the StyleDataGridRow style as the base style for priceMissing.
<UserControl.Resources>
<ResourceDictionary>
<Style x:Key="priceMissing" TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource StyleDataGridRow}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=priceIsMissing}" Value="true">
<Setter Property="Background" Value="LightSalmon" />
</DataTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</UserControl.Resources>
Then use the priceMissing style in your DataGrid.
<DataGrid x:Name="dgCalculatedServices
...
RowStyle="{StaticResource priceMissing}">
You could of course rename the priceMissing style to StyleDataGridRow instead. The style would then be overwritten in the scope of the UserControl.

How can I style only those Buttons which are in a DataGrid?

In App.xaml I have styled all my Buttons.
<Style TargetType="Button">
<Setter Property="Margin" Value="3"/>
</Style>
I realized if the Button is in a DataGrid then I not need a margin. I have a lot of DataGrid and I put this code into all of them one by one.
<DataGrid.Resources>
<Style TargetType="Button">
<Setter Property="Margin" Value="0"/>
</Style>
</DataGrid.Resources>
Is there a more clever way to do this?
You can define Style for DataGrid and within that, add child control style to particular modification.
If you want to add this Style to all the DataGrids, no need to defineKey.
<Style x:Key="dataGrid" TargetType="DataGrid">
<Style.Resources>
<Style TargetType="Button">
<Setter Property="Margin" Value="0" />
</Style>
</Style.Resources>
</Style>
Declare a style with the key in the Window.Resources or App.Resources as shown below.
<Window.Resources>
<Style TargetType="Button" x:Key="dataGridButtonStyle">
<Setter Property="Margin" Value="3"/>
<Setter Property="Background" Value="Wheat"/>
</Style>
</Window.Resources>
Then apply the style to the control using the StaticResource with the key(in this example key name is dataGridButtonStyle)
<Button Style="{StaticResource ResourceKey= dataGridButtonStyle}" Content="Hello"/>
Please add resource file at Windows or User control level so that it will apply all child controls as below,
<Window.Resources>
<Style TargetType="DataGrid">
<Style.Resources>
<Style TargetType="Button">
<Setter Property="Background" Value="Red" />
<Setter Property="Margin" Value="0" />
</Style>
</Style.Resources>
</Style>
<Window.Resources>
or
<UserControl.Resources>
<Style TargetType="DataGrid">
<Style.Resources>
<Style TargetType="Button">
<Setter Property="Background" Value="Red" />
<Setter Property="Margin" Value="0" />
</Style>
</Style.Resources>
</Style>
</UserControl.Resources>

How to base a style on an inherited style

So I have a Master Detail page. And in my Master page I have a style that will set the style for all buttons.
Master Page
<Style TargetType="Button">
<Setter Property="Background" Value="White" />
<Setter Property="TextBlock.TextAlignment" Value="Center" />
<Setter Property="RenderTransformOrigin" Value="-0.893,-11.7"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
in my Detail Page I have a button where I would like to add some triggers to through the style
<Button Content="{Binding DeleteMultipleButton}" Margin="0,0,5,0" CommandParameter="{Binding ElementName=files, Path=SelectedItems}" Command="{Binding DeleteMultipleFiles}">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="IsEnabled" Value="True"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Deleting}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
But this overwrites the inherited style and I lose my button styling. Is there a way I can base my button style on the inherited style? (I can't do this through static resource and a key because the resource is in a different page)
You can use the BasedOn property:
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
Keep your base button style as it is:
<Style TargetType="Button">
<Setter Property="Background" Value="White" />
<Setter Property="TextBlock.TextAlignment" Value="Center" />
<Setter Property="RenderTransformOrigin" Value="-0.893,-11.7"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
And apply the BasedOn property to the button on the Detail Page:
<Button>
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
...
</Style>
</Button.Style>
</Button>
So Because the two styles were on different pages it makes inheriting from the default style impossible so what I did was build an App.xaml resource file with my style in it and then on both pages add the code:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resource.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
to my xaml. This meant that my page was then able to override the inherited style by using Mike Eason's code:
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">

I can not apply the Style for custom UserControl

I can not apply the Style for custom UserControl.
Styles for TextBlock and MyControl are in the same dictionary.
Style for TextBlock used without problems.
But for MyControl style is not applied.
Why?
// XAML
xmlns:local="clr-namespace:MyControlNameSpace"
<Grid>
<TextBlock x:Name="text" Style="{DynamicResource TextStyle}"/>
<local:MyControl x:Name="control" Style="{DynamicResource ControlStyle}"/>
</Grid>
// RESOURCE DICTIONARY
<Style x:Key="ControlStyle" TargetType="{x:Type local:MyControl}">
<Setter Property="Height" Value="Auto"/>
<Setter Property="Width" Value="Auto"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="ColorMain" Value="Black"/>
<Setter Property="Margin" Value="2"/>
</Style>
<Style x:Key="TextStyle" TargetType="{x:Type TextBlock}">
....
<Setter Property="FontSize" Value="32"/>
...
</Style>
//PART of CS
public partial class MyControl: UserControl { .... }
Try changing
<Setter Property="ColorMain" Value="Black"/>
To
<Setter Property="Background" Value="Black"/>

Categories