How to change the display data format of the WPF DatePicker - c#

I got this sample code from this forum.
<DatePicker SelectedDate="{Binding MainReportEndDate, Mode=TwoWay}"
DataContext="{Binding DataContext, RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type GroupBox}}}"
DisplayDateStart="1/01/20" DisplayDateEnd="12/31/22"
FirstDayOfWeek="Monday"">
<DatePicker.Resources>
<Style TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<TextBox x:Name="PART_TextBox"
Text="{Binding Path=SelectedDate,
RelativeSource={RelativeSource AncestorType={x:Type DatePicker}},
StringFormat={}{0:MMM yy}}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DatePicker.Resources>
</DatePicker>
But it doesn't work. I want the same result as the one in the picture "Jul 20"

Try this
<TextBox x:Name="PART_TextBox"
Text="{Binding Path=SelectedDate, StringFormat='dd MMM yyyy',
RelativeSource={RelativeSource AncestorType={x:Type DatePicker}}}" />

Related

how to add a customtext to datepicker text box

i designed a textbox foe date picker but i cant add a custom text inside the textbox before choosing date.i want to add "select a date"
<Grid>
<DatePicker x:Name="DateGviya" SelectedDate="{Binding CurrentDate}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="97,77,0,0">
<DatePicker.Resources>
<Style TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<TextBox x:Name="PART_TextBox" Text="{Binding Path=SelectedDate, StringFormat='dd/MM/yyyy hh:mm:ss tt', RelativeSource={RelativeSource AncestorType={x:Type DatePicker}}}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DatePicker.Resources>
</DatePicker>
</Grid>
result is like this:
You could use the TargetNullValue property of the binding:
<DatePicker x:Name="DateGviya" SelectedDate="{Binding CurrentDate}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="97,77,0,0">
<DatePicker.Resources>
<Style TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<TextBox x:Name="PART_TextBox"
Text="{Binding Path=SelectedDate,
StringFormat='dd/MM/yyyy hh:mm:ss tt',
RelativeSource={RelativeSource AncestorType={x:Type DatePicker}},
TargetNullValue='Select a Date'}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DatePicker.Resources>
</DatePicker>

WPF ComboBox Ensure ItemTemple UserControl inherits Background And Foreground From ComboBox

I have a ComboBox,
<ComboBox Grid.Row="1"
Margin="5"
ItemsSource="{Binding PreviousGroups, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedGroup, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
Style="{DynamicResource CBComboBoxStyle}"
ItemContainerStyle="{DynamicResource CBItemContainerStyle}">
<ComboBox.ItemTemplate>
<DataTemplate>
<objects:GroupNameObject GroupName="{Binding Path=Name}"
LastChecked="{Binding Path=LastVerified, StringFormat='dd - MM - yyyy |T| hh : mm : ss'}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
which uses the item template GroupNameObject
<UserControl x:Class="MyProject.Objects.GroupNameObject"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:fa="http://schemas.awesome.incremented/wpf/xaml/fontawesome.sharp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Name="groupNameObject">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MyProject;component/Assets/Colors.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Border Padding="3"
CornerRadius="10"
Margin="3"
HorizontalAlignment="Stretch">
<Border.Style>
<Style TargetType="Border">
<Setter Property="Background"
Value="Transparent" />
</Style>
</Border.Style>
<StackPanel Orientation="Horizontal">
<Grid Width="40"
Height="40"
Margin="5 2 3 2">
<Border CornerRadius="10"
Background="{Binding Path=Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBoxItem}}}" />
<StackPanel Orientation="Horizontal"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<fa:IconImage Icon="Folder"
Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBoxItem}}}"
Width="30" />
</StackPanel>
</Grid>
<StackPanel>
<TextBlock Text="{Binding Path=GroupName, ElementName=groupNameObject}"
FontSize="20"
FontWeight="Bold"
Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBoxItem}}}"
Margin="5 0" />
<TextBlock FontSize="12"
Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBoxItem}}}"
Margin="5 3">
<Run Text="{Binding Path=LastChecked, ElementName=groupNameObject, StringFormat='MM / dd / yyyy |T| HH : mm : ss'}" />
</TextBlock>
</StackPanel>
</StackPanel>
</Border>
with the ItemContainerStyle
<Style x:Key="CBItemContainerStyle"
TargetType="{x:Type ComboBoxItem}">
<Setter Property="HorizontalContentAlignment"
Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment"
Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Padding"
Value="3,0,3,0" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
<Border x:Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted"
Value="true">
<Setter Property="Background"
Value="{DynamicResource LemonCurry}" />
<Setter Property="Foreground"
Value="{DynamicResource LogoBlue}" />
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Background"
Value="{DynamicResource PansyPurple}" />
<Setter Property="Foreground"
Value="{DynamicResource LemonCurry}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
When Built the DropDownItems inherit the Background and Foreground items correctly But the Displayed Item doesn't.
Display Item Example
DropDown Items Example
How Can I Change the Background and Foreground of the Displayed Item?
Edit:
Finally found a work around. instead of Binding the foreground and background of the GroupNameObject to the ComboBoxItem, I bound it to The ComboBox.
<StackPanel Orientation="Horizontal">
<Grid Width="40"
Height="40"
Margin="5 2 3 2">
<Border CornerRadius="10"
Background="{Binding Path=Background, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}}" />
<StackPanel Orientation="Horizontal"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<fa:IconImage Icon="Folder"
Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}}"
Width="30" />
</StackPanel>
</Grid>
<StackPanel>
<TextBlock Text="{Binding Path=GroupName, ElementName=groupNameObject}"
FontSize="20"
FontWeight="Bold"
Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}}"
Margin="5 0" />
<TextBlock FontSize="12"
Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}}"
Margin="5 3">
<Run Text="{Binding Path=LastChecked, ElementName=groupNameObject, StringFormat='MM / dd / yyyy |T| HH : mm : ss'}" />
</TextBlock>
</StackPanel>
</StackPanel>
and in the ItemContainerStyle I changed the Highlight Color to a diffrent shade so it doesn't clash with the ComboBox Colors.
<Trigger Property="IsHighlighted"
Value="true">
<Setter Property="Background"
Value="{DynamicResource BlueSapphire}" />
</Trigger>
Display Item After
DropDown Items After
You may have to override the ComboBox Template Property as well:
Example
<Style TargetType="ComboBox" BasedOn="{StaticResource baseStyle}">
<Setter ... />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ComboBox">
<Grid
x:Name="templateRoot"
UseLayoutRounding="True"
SnapsToDevicePixels="True"
>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="18" />
</Grid.ColumnDefinitions>
<Popup>
...
</Popup>
<ToggleButton>
...
</ToggleButton>
<ContentPresenter
x:Name="contentPresenter"
Grid.Column="0"
...
/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
Inside this ToggleButton is the Layout for your ComboBox

Trigger to set Property in ItemTemplate

I have the following definition of a UserControl
<UserControl x:Class="Logger.View.AdvancedToggleButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:converter="clr-namespace:Logger.Converter"
xmlns:commonControls="clr-namespace:Logger.CommonControls"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<UserControl.Resources>
<converter:CountToVisibilityConverter x:Key="CountToVisibilityConverter" />
</UserControl.Resources>
<ItemsControl ItemsSource="{Binding LogElements, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.Resources>
<Style TargetType="{x:Type ToggleButton}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="container"
BorderThickness="1" Margin="1,2,1,1" Padding="2,2,4,2" BorderBrush="Black">
<ContentPresenter x:Name="contentPresenter" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" TargetName="container" Value="{Binding SelectionBrush, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
<Setter Property="BorderThickness" TargetName="container" Value="1,1,1,0"></Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Background" TargetName="container" Value="{Binding SelectionBrush, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
<Setter Property="Background" Value="{Binding SelectionBrush, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ToggleButton Margin="2,1"
IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
Command="{Binding DataContext.ToggleCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
CommandParameter="{Binding}">
<ToggleButton.Content>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="4,0,5,0" x:Name="tbText"/>
<Border Grid.Column="1" Margin="0,-1,-3,-1" MinWidth="20"
VerticalAlignment="Stretch" HorizontalAlignment="Center"
Background="Yellow" BorderBrush="LightGray" BorderThickness="1,0,0,0"
Visibility="{Binding WarningCount, Converter={StaticResource CountToVisibilityConverter}}"
Cursor="Hand">
<commonControls:ActionLink HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding WarningCount}"
FontFamily="Consolas" Margin="2,0" Command="{Binding DataContext.NavigateToWarningCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
</Border>
<Border Grid.Column="2" Margin="3,-1,-3,-1" MinWidth="20"
VerticalAlignment="Stretch" HorizontalAlignment="Center"
Background="Red" BorderBrush="LightGray" BorderThickness="1,0,0,0"
Visibility="{Binding ErrorCount, Converter={StaticResource CountToVisibilityConverter}}"
Cursor="Hand" >
<commonControls:ActionLink HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding ErrorCount}"
FontFamily="Consolas" Foreground="White" Margin="2,0" />
</Border>
</Grid>
</ToggleButton.Content>
</ToggleButton>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</UserControl>
Everything just works fine. Now I've added another Property to this UserControl to set the BackgroundColor of the Checked ToggleButton-TextBlock (tbText) to a given SolidColorBrush.
My problem now is, that I have no idea how to correctly set the Trigger for this.
I tried to add the Trigger to the ControlTemplate.Triggers when the IsChecked is True. But I don't know how to access tbText from this point. Is this the correct location for the Trigger or do I have to add another Trigger at a lower level?
Your ToggleButton.IsChecked property is data bound to your IsSelected property so by default, you also want to set the TextBlock.Background when this IsSelected property is true. You can do that like this:
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="4,0,5,0"
x:Name="tbText">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter Property="Background" Value="{Binding YourColourBrush,
RelativeSource={RelativeSource AncestorType={x:Type
YourPrefix:YourUserControl}}}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
Alternatively, you could just data bind directly to the ToggleButton.IsChecked property like this:
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" Margin="4,0,5,0"
x:Name="tbText">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource
AncestorType={x:Type ToggleButton}}}" Value="True">
<Setter Property="Background" Value="{Binding YourColourBrush,
RelativeSource={RelativeSource AncestorType={x:Type
YourPrefix:YourUserControl}}}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>

How to get this binding for item instead of TreeViewItem?

I got the following code :
<HierarchicalDataTemplate x:Key="AssignedRate" ItemsSource="{Binding Children}" DataType="{x:Type local:UnitRateCatElement}">
<ContentControl>
<ContentControl.Template>
<ControlTemplate>
<StackPanel Tag="{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">
<TextBlock Text="{Binding Category.Description}" />
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="Add Unit Rate"
Command="{Binding Path=PlacementTarget.Tag.AddUnitRateCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
</ControlTemplate>
</ContentControl.Template>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsDefined, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock Text="Hello, it works!" />
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</HierarchicalDataTemplate>
The binding in the line : <DataTrigger Binding="{Binding Path=IsDefined, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}" Value="True">
is incorrect (VS says so). How can I get this to work? The class local:UnitRateCatElement does have a IsDefined property. But I cannot get the binding right to point to that object. How can I get this binding right?
Try
Binding="{Binding Path=DataContext.IsDefined, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}"
I think you should be doing this -
<DataTrigger Binding="{Binding Path=DataContext.IsDefined,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type TreeViewItem}}}" Value="True">
as your RelativeSource binding points to the TreeViewItem, which doesn't have IsDefined property, it is present in the DataContext of the TreeViewItem.
Update:
For your second problem (trigger not working), this is happening because you are setting the Template explicitly i.e. Local Value which is having higher precedence then Triggers; this should work -
<ControlTemplate x:Key="DefaultTemplate">
<StackPanel Tag="{Binding DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}">
<TextBlock Text="{Binding Category.Description}" />
<StackPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="Add Unit Rate"
Command="{Binding Path=PlacementTarget.Tag.AddUnitRateCommand, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
</ContextMenu>
</StackPanel.ContextMenu>
</StackPanel>
</ControlTemplate>
<ControlTemplate x:Key="DefinedTemplate">
<TextBlock Text="Hello, it works!" />
</ControlTemplate>
<HierarchicalDataTemplate x:Key="AssignedRate" ItemsSource="{Binding Children}"
DataType="{x:Type local:UnitRateCatElement}">
<ContentControl>
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Template" Value={StaticResource DefaultTemplate}>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=DataContext.IsDefined, RelativeSource=
{RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}}}"
Value="True">
<Setter Property="Template" Value={StaticResource DefinedTemplate}>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</HierarchicalDataTemplate>

Binding from DataTrigger

Trying to bind to the Tag property of a textbox from a datatrigger, but doesnt seem to get the binding corrrect
Partial xaml
<TextBox Grid.Column="2" Tag="Enter password" Text="{Binding UserName, Mode=TwoWay}" Name="textBox1" Width="200" Height="25" HorizontalAlignment="Left" >
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="">
<Setter Property="Background">
<Setter.Value>
<VisualBrush Stretch="None">
<VisualBrush.Visual>
<TextBlock Text="{Binding
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type TextBox}},
Path=Tag}"
Foreground="Gray"/>
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
Its the part
<TextBlock Text="{Binding
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type TextBox}},
Path=Tag}"
that is not working. I have tried a couple of solutions, but textbox is always ending up empty.

Categories