I need to limit the date range of all DatePicker controls in an existing WPF application to limit input errors by users.
I thought about using a global style similar to this:
<Style TargetType="DatePicker">
<Setter Property="CalendarBlackoutDatesCollection">
<Setter.Value>
<CalendarDateRange Start="1/1/1999" End="1/1/2100"/>
</Setter.Value>
</Setter>
</Style>
But I can not find the right way to define this. Can someone give me a hint how to achive this? It should be a solution to control this behavior a one point for all DatePickers of the app.
The blackout dates define dates that should be crossed out and not selectable. I guess that you meant to allow dates that fall into the defined range only. In order to do that, define a DisplayDateStart and a DisplayDateEnd.
<Style x:Key="MyDatePickerStyle" TargetType="{x:Type DatePicker}" BasedOn="{StaticResource {x:Type DatePicker}}">
<Setter Property="DisplayDateStart" Value="1/1/1999"/>
<Setter Property="DisplayDateEnd" Value="1/1/2100"/>
</Style>
Reference this style in each DatePicker that you want to limit the date range for.
<DatePicker Style="{StaticResource MyDatePickerStyle}"/>
If you want to apply the style to all DatePickers automatically in the scope where the style is defined without having to specify the Style on each one manually, you can remove the x:Key from the style to make it a so called implicit style.
<Style TargetType="{x:Type DatePicker}" BasedOn="{StaticResource {x:Type DatePicker}}">
If you want to apply the style to all DatePickers, define it in the application resources.
Related
I don't know if I've phrased myself correctly, so let me further explain.
I have a lot of ListViews in my project. And they all use the same ListViewItem style, which is a pretty big chunk of code, so I keep it in App.xaml as a static resource, so I can just reference it from anywhere.
Now my issue is that, for each ListViewItem, I want to have a distinct MouseEvent handler. As much as I understand, these MouseEvents need to be defined in Style for ListViewItems.
So I went ahead and made something like this (in the App.xaml):
<Style x:Key="ListViewItemStyle" TargetType="{x:Type ListViewItem}">
<!-- A lot of setters -->
<EventSetter Event="MouseDown" Handler="MyHandler"/>
</Style>
My question is, how exactly could I create a separate MyHandler for every object that uses this style.
Also, I am not really sure that this is the best approach, so other suggestions are welcome.
If you want to have a distinct handler for every ListView that uses ListViewItemStyle, you can create an individualized style for that ListView which is BasedOn ListViewItemStyle:
<Style x:Key="ListViewItemStyle" TargetType="{x:Type ListViewItem}">
<!-- A lot of setters -->
</Style>
...
<ListView>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem" BasedOn="{StaticResource ListViewItemStyle}">
<EventSetter Event="MouseDown" Handler="MyHandler"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
In this way, your individualized styles inherit all the Setters and Triggers from ListViewItemStyle, but you can also add more on top of those.
I know I'm a pervert, but I am very curious, is there a way to make custom controls to seek for it's base class style first, and then it's own.
Why I'm asking: I have some TreeView derived controls with custom item templates. I apply those templates, then I have a base style. Later I might apply some color palette. At the last step I have a problem. I need to apply 2 styles. PVStructuralTree is derived from TreeView it has some DependencyProperty DataTemplates that get inserted into resources in code.
PVStructuralTreeView
EmploeeTemplate
... more templates
Default style for PVStructuralTreeView:
<Style x:Key="DefaultPVStructuralTreeView" TargetType="{x:Type c:PVStructuralTreeView}" BasedOn="{StaticResource DefaultTreeView}">
<Setter Property="EmploeeTemplate"><!-- This get inserted inro Resources in code -->
<Setter.Value>
<DataTemplate DataType="{x:Type s:Emploee}">
...
</DataTemplate>
</Setter.Value>
</Setter>
... Lots of them here
</Style>
<Style TargetType="{x:Type c:PVStructuralTreeView}" BasedOn="{StaticResource DefaultPVStructuralTreeView}"/>
Default style for a TreeView (it's pretty big, so I won't post it here):
<Style TargetType="{x:Type TreeView}" BasedOn="{StaticResource DefaultTreeView}"/>
In color template.xaml file I'd like to have this + some magic to apply both styles at the same time (from Generic.xaml and themed one):
<Style x:Key="ThemedTreeView" TargetType="{x:Type TreeView}" BasedOn="{StaticResource DefaultTreeView}">
...
</Style>
<Style TargetType="{x:Type c:PVStructuralTreeView}" BasedOn="{StaticResource ThemedTreeView}"/>
But it just overwrites generic.xaml styles. I want it to add to it.
Now I'm doing this way:
<Style x:Key="ThemedPVStructuralTreeView" TargetType="{x:Type c:PVStructuralTreeView}" BasedOn="{StaticResource DefaultPVStructuralTreeView}">
... CopyPaste from ThemedTreeView ...
</Style>
<Style TargetType="{x:Type c:PVStructuralTreeView}" BasedOn="{StaticResource ThemedPVStructuralTreeView}"/>
Does anyone knows the way how to reuse the ThemedTreeView style here?
You can base a Style on Another (one only!) Style using the BasedOn property and override specific properties, but you cannot base a DataTemplate or a ControlTemplate on another template. This is not supported. A template must be defined as a whole:
WPF: Is there a way to override part of a ControlTemplate without redefining the whole style?
I am styling CellValuePresenter (From Infragistics) to give different look to Gid Lines and have defined a style (gridLineStyle) and applied to the Grid's CellValuePresenterStyle Property.
I have discovered that there are columns for which custom templates are defined by templating CellValuePrenter and the grid lines are not visible (as expected). I can make it work by applying BasedOn property as in
<Style x:Key="gridLineStyle" TargetType="ig:CellValuePresenter">
<Setter Property="BorderThickness" Value="0,0,1,1"/>
<Setter Property="BorderBrush" Value="{Binding Path=BorderBrushForAllCells,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type pwc:CarbonBlotter}}}"/>
</Style>
<Style x:Key="anotherColumnStyle" TargetType="{x:Type ig:CellValuePresenter}" BasedOn="{StaticResource gridLineStyle}">
<Setter Property="Template">
....
<pwc:BaseXamDataGrid>
<pwc:BaseXamDataGrid.FieldSettings>
<ig:FieldSettings CellValuePresenterStyle="{StaticResource gridLineStyle}"
...
But there are many styles with custom templates, and just wondering whether I can define a style without using BasedOn property and yet inheriting default style
You can find the complete CellValuePresenter style definition in your infragistics installation folder under DefaultStyles\DataPresenter\DataPresenterGeneric_Express.xaml
You can copy that style into your App.xaml under Application.Resources, modify it as you wish and that should become your new default style for CellValuePresenter.
How do I change what WPF's idea of the default style for a control is? And why is this happening in the first place? In the below XAML, I declare a Style for Button, and then further declare a new Style that overrides one of the setters called "HugeBut". I would expect that HugeBut is implicitly BasedOn my new un-named style, but apparently it is not;
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="Red">
<ContentPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- badness -->
<Style TargetType="{x:Type Button}" x:Key="HugeBut">
<Setter Property="Foreground" Value="Yellow"/>
</Style>
<!-- works, but I do not want to explicitly set the based-on. -->
<Style TargetType="{x:Type Button}" x:Key="HugeBut" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Foreground" Value="Yellow"/>
</Style>
</Window.Resources>
<Button Content="Regular" />
<Button Content="huge!" Style="{StaticResource HugeBut}"/>
You would expect two red buttons, one with black text and one with yellow, but Style HugeBut inherits all of the values that I did not specify in my unnamed style from the system default theme for Button (Aero in my case).
What can I do to change this behavior?
It appears that the answer is here:
http://wpfthemereplacer.codeplex.com/
From the site description:
This library allows users to provide their own resource dictionaries
to replace the default theme dictionaries loaded by WPF. This makes it
so you don't have to decorate custom styles with
BasedOn="{StaticResource {x:Type ...}}" when your own custom theme is
being used in your application. It also makes it so if you have custom
controls that just provide enhanced capability and don't need to
replace the the style, you don't need to define a new style or
override the DefaultStyleKey when you create the custom control.
This is exactly what I'm looking for. This will allow me to use Styles as they are meant to be used across an app that has been extensively "re-themed", rather than theme-ing by setting global styles (and then deal with tracking down bits of code that are missing BasedOn, or cannot deal with it at all due to WPF bugs and other constraints)
works, but I do not want to explicitly set the based-on.
Well, the framework does not really care if you don't want to, for all i know, you have to.
Is there a way to create a style that extends the current style, i.e. not a specific style?
I have a WPF application where I create styles to set some properties like borders or validation.
<Style TargetType="{x:Type Button}"
BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Padding" Value="5,2,5,2"/>
</Style>
Now I want to try out some Themes to see which one works best for my application. Problem is that to do that I need to change the BasedOn property on all my Styles to the style in the Theme.
<Style TargetType="{x:Type Button}"
BasedOn="="{x:Static ns:SomeTheme.ButtonStyle}">">
<Setter Property="Padding" Value="5,2,5,2"/>
</Style>
I can do it via search/replace but it would be nice if it could be done dynamicly.
You need to do it in this way only, there is no shortcut to do this, you have to set BasedOn attribute atleast.
if you store all your resources in seperate assemblies from your ui then you can use themes to dynamically change them at runtime.
themes in seperate assembly
loading different themes at runtime
Have you tried DynamicResource instead of StaticResource.