I'm relative new to WPF and I have check on several tutorials on how to style a DataGrid. All of them use the same examples but when I try to implement them into my project, came this annoying message.
This is the code I've been trying to implement, I got this from MSDN page:
<Window.Resources>
<!-- DataGrid style -->
<Style x:Key="DataGridStyle1" TargetType="{x:Type DataGrid}">
<Setter Property="ColumnHeaderStyle" Value="{DynamicResource ColumnHeaderStyle1}"/>
</Style>
<!-- DataGridColumnHeader style -->
<Style x:Key="ColumnHeaderStyle1" TargetType="DataGridColumnHeader">
<Setter Property="Height" Value="30"/>
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="FontSize" Value="18" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="ToolTip" Value="Click to sort."/>
</Trigger>
</Style.Triggers>
</Style>
I'm using:
- C# Framework 4.5.1
- Blend for Visual Studio 2013
- Visual Studio 2013 (I got the error in both places).
All the imports and references are just fine.
I have check the solution properties and my Platform Target is "Any CPU"
My guess is this property might be deprecated for this control (DataGridColumnHeader).
Hope anyone could tell the proper way to acheive my goal.
Thanks in advance
It's trying to use a DynamicResource before it's defined.. Try swapping the Styles. Also, there's really no need for a DynamicResource here IMO, just change it to StaticResource.
<Window.Resources>
<!-- DataGridColumnHeader style -->
<Style x:Key="ColumnHeaderStyle1" TargetType="DataGridColumnHeader">
<Setter Property="Height" Value="30"/>
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="Foreground" Value="Blue"/>
<Setter Property="FontSize" Value="18" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="ToolTip" Value="Click to sort."/>
</Trigger>
</Style.Triggers>
</Style>
<!-- DataGrid style -->
<Style x:Key="DataGridStyle1" TargetType="{x:Type DataGrid}">
<Setter Property="ColumnHeaderStyle" Value="{StaticResource ColumnHeaderStyle1}"/>
</Style>
</Window.Resources>
Related
I am developing a WPF Application using Mahapps.Metro library.
There is a DataGrid where I want to use a ContextMenu on the added rows, for that I am defining this in datagrid resources
<DataGrid.Resources>
<ContextMenu x:Key="RowMenu"
DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Borrar detalle" Click="delete_Click" />
<MenuItem Header="Editar detalle" Click="edit_Click" />
</ContextMenu>
</DataGrid.Resources>
and adding that context menu in the rowstyle
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" >
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" />
</Style>
</DataGrid.RowStyle>
The problem with this is that when user clicks on the row, it seems to disappear (the font color turns white).
I tried adding the following to the rowstyle but it does not seems to work.
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" >
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="LightSkyBlue"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="LightSkyBlue"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="Transparent"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
MY last option is to use the contextmenu in the grid instead rows, but I want to know if there is something I can do to make this work.
Hope you can help, thanks.
You should use based-on feature on your defined style:
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" BasedOn="{StaticResource {x:Type DataGridRow}}">
<Setter Property="ContextMenu" Value="{StaticResource RowMenu}" />
</Style>
</DataGrid.RowStyle>
Please i need a way to come up with a style like these
But this is the current one i'm using
Please if you can help out with maybe a Link, Code, Tutorial on how to get it done, i'll greatly appreciate. Thanks..
Modifying the styles of a MenuItem (WPF) is more complicated than it might seem, because the same MenuItem control uses different templates depending on the Role assigned to each MenuItem: SubmenuItem, TopLevelHeader and SubmenuHeader.
With the menu bar you should not have any problem: if you want, you can define your style and your template as with any other control. For MenuItem, try something like this:
<ControlTemplate x:Key="{x:Static MenuItem.SubmenuItemTemplateKey}" TargetType="{x:Type local:MyMmenuItem}">
...
</ControlTemplate>
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelHeaderTemplateKey}" TargetType="{x:Type local:MyMenuItem}">
...
</ControlTemplate>
<ControlTemplate x:Key="{x:Static MenuItem.SubmenuHeaderTemplateKey}" TargetType="{x:Type local:MyMenuItem}">
...
</ControlTemplate>
And to switch between different templates, we will use the RoleProperty dependency property, defining these triggers in our style:
<Style x:Key="MyMenuItemStyle" TargetType="{x:Type local:MyMenuItem}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Style.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Template" Value="{StaticResource {x:Static MenuItem.TopLevelHeaderTemplateKey}}"/>
</Trigger>
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Template" Value="{StaticResource {x:Static MenuItem.TopLevelItemTemplateKey}}"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="Template" Value="{StaticResource {x:Static MenuItem.SubmenuHeaderTemplateKey}}"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuItem">
<Setter Property="Template" Value="{StaticResource {x:Static MenuItem.SubmenuItemTemplateKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
I hope this works for you; It worked for me when I faced the same problem.
Good luck, good code.
how do I go about binding the Foreground Colour of one Style setter to the Fill Colour on another Style Setter, it should be the same object type. This is the code I have got below!
Getting these errors:
System.Windows.Data Error: 4 : Cannot find source for binding with
reference 'ElementName=MenuItemPath'. BindingExpression:Path=Fill;
DataItem=null; target element is 'TextBlock' (Name=''); target
property is 'Foreground' (type 'Brush')
<Style x:Key="MenuItemName" TargetType="TextBlock">
<Setter Property="Foreground" Value="{Binding ElementName=MenuItemPath, Path=Fill}" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
<ControlTemplate x:Key="MenuItem" TargetType="RadioButton">
<ControlTemplate.Resources>
<Style TargetType="Path" x:Name="MenuItemPath">
<Setter Property="Fill" Value="#FF22252C" />
<Setter Property="Height" Value="25" />
<Setter Property="Width" Value="25" />
<Setter Property="Stretch" Value="Uniform" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type RadioButton}}, Path=IsChecked}" Value="True">
<Setter Property="Fill" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
</ControlTemplate.Resources>
Personally I would create a separate Resource for storing the brush color, and reference it from both locations.
<SolidColorBrush Color="#FF22252C" x:Key="MenuFillColor" />
<Style x:Key="MenuItemName" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource MenuFillColor}" />
...
</Style>
<ControlTemplate x:Key="MenuItem" TargetType="RadioButton">
<ControlTemplate.Resources>
<Style TargetType="Path" x:Name="MenuItemPath">
<Setter Property="Fill" Value="{StaticResource MenuFillColor}" />
...
</Style>
</ControlTemplate.Resources>
</ControlTemplate>
That said, I've never actually tried binding to another Style's Setter.Value property... it might be possible assuming everything was the same scope. You look like you may have different scopes since you are using <ControlTemplate.Resources> to limit the scope of your MenuItemPath style to just that ControlTemplate. But personally I would not attempt it, and would assume any requirement that needed something like this could also be done some better way :)
It is not possible to access outer property of another style in wpf and that's why you have got binding error. Rather you can declare a color in your resources and from where you can access it.
I was making it more complicated than need be, I just added a DataTrigger which fixed the issue:
<Style x:Key="MenuItemName" TargetType="TextBlock">
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=MenuItemRadio}" Value="True">
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
I am working in WPF with the MaterialDesign Toolkit and Dragablz.
I encountered a problem while trying to style a TabablzControl.
I already have style for the windows default TabControl and TabItem header, as shown in the picture:
http://i.imgur.com/2anl5rl.png
But when I change the default tabControl to TabablzControl, it turns into this:
http://i.imgur.com/bhaaMVy.png
Here are the window.resources:
<Style x:Key="mdTabControl" TargetType="TabControl">
<Setter Property="TextElement.Foreground" Value="{DynamicResource MaterialDesignBody}"/>
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"></Setter>
</Style>
<Style x:Key="mdTabHeader" TargetType="{x:Type TabItem}">
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"></Setter>
<Setter Property="Foreground" Value="{DynamicResource MaterialDesignBody}"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border" Margin="1,0,1,0" CornerRadius="3 3 0 0">
<ContentPresenter x:Name="ContentSite" VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header" Margin="10,2,10,2"
RecognizesAccessKey="True">
</ContentPresenter>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="Background" Value="{StaticResource SecondaryAccentBrush}" />
<Setter Property="Foreground" Value="{StaticResource SecondaryAccentForegroundBrush}"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="Background" Value="{StaticResource PrimaryHueMidBrush}" />
<Setter Property="Foreground" Value="{StaticResource PrimaryHueMidForegroundBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="{StaticResource PrimaryHueDarkBrush}" />
<Setter Property="Foreground" Value="{StaticResource PrimaryHueDarkForegroundBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The error appears when I change the mdTabControl style targetType to:
TargetType="dbz:TabablzControl"
I want to keep the style I set to the TabControl, but with the added functionality of the TabablzControl
Any help will be appreciated
First thing to note, which is a general WPF characteristic, you are not using style inheritance correctly.
As you are using Material Design with Dragablz, if you are restyling the tab control itself, you must inherit from the Material Design style in the Dragablz assembly using BasedOn:
<Style x:Key="mdTabControl" TargetType="TabControl" BasedOn="{StaticResource MaterialDesignTabablzControlStyle}">
<Setter Property="TextElement.Foreground" Value="{DynamicResource MaterialDesignBody}"/>
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"></Setter>
</Style>
Again, with the tab header itself, you need to inherit from the relevant style:
<Style x:Key="mdTabHeader" TargetType="{x:Type TabItem}" BasedOn="{StaticResource MaterialDesignDragableTabItemStyle}">
. . .
</Style>
Note, that (depending you your App.xaml setup) you probably need to make sure the correct resource dictionary is included in the same XAML file. For example a more complete XAML might be:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/materialdesign.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="NormalTabItemStyle" TargetType="{x:Type dragablz:DragablzItem}" BasedOn="{StaticResource MaterialDesignDragableTabItemStyle}">
<Setter Property="Width" Value="280" />
<Setter Property="Padding" Value="1" />
</Style>
. . .
</ResourceDictionary>
</Window.Resources>
Finally, as you are changing the TabItem style, you either need to the TabablzCOntrol style the correct style, or you could use it where you actually declare the TabablzControl itself:
<dragablz:TabablzControl ItemContainerStyle="{StaticResource mdTabHeader}" />
A good example of all this in action is in the SidePanels project in the demo solution at: https://github.com/ButchersBoy/DragablzSamplez
<Style TargetType="{x:Type dragablz:TabablzControl}" BasedOn="{StaticResource MaterialDesignTabablzControlStyle}"/>
I'm currently working with MVVM in WPF, I installed MahappsMetro in my project. I want to change the default DataGrid style, without losing all the properties of MetroDataGrid style (Style for DataGrid from MahappsMetro).
I simply want to change some Triggers as IsMouseOver and IsSelected, I tried doing this:
I defined this Style in App.xaml
<Style x:Key="TransparentDataGrid" TargetType="{x:Type DataGrid}" BasedOn="{StaticResource MetroDataGrid}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGrid}">
<DataGrid>
<DataGrid.RowStyle>
<Style TargetType="{x:Type DataGridRow}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.RowStyle>
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="DataGridCell.IsSelected" Value="True">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Foreground" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
</DataGrid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And I bind this Style, where I need it
Style="{DynamicResource TransparentDataGrid}"
But I get the exception :
A first chance exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll
Also I tried :
I created the style in MainViewModel.xaml but I don't know how to bind this style to other views.
to derive from existing style for the controls you need to specify the type as the key in based on attribute
<Style x:Key="TransparentDataGrid" TargetType="{x:Type DataGrid}" BasedOn="{StaticResource {x:Type MetroDataGrid}}">
<Setter Property="Template">
<Setter.Value>
...
if above does not work then do prefix with correct namespace to MetroDataGrid eg mapp:MetroDataGrid where mapp points to MahappsMetro assembly
eg
<Application x:Class="CSharpWPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
xmlns:mapp="clr-namespace:MahApps.Metro.Controls">
<Application.Resources>
<Style x:Key="TransparentDataGrid" TargetType="{x:Type DataGrid}" BasedOn="{StaticResource {x:Type mapp:MetroDataGrid}}">
<Setter Property="Template">
<Setter.Value>
...
</Application.Resources>
use the correct assembly above is just an example