我正在尝试在
TextBox
控件中使用自定义 DatePicker
,但我无法将弹出日历中的日期绑定到 TextBox
。除非必须,否则我不想对整个 DatePicker
进行样式设置,并且 DatePickerTextBox
有自己的控件,因此必须有一种方法只能更改它。下面的代码是我的开始:
<Style TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePickerTextBox}">
<TextBox x:Name="PART_TextBox" Text="{Binding Path=SelectedDate}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我可能没有正确进行绑定,或者
PART_TextBox
可能不正确,因为它不是 DatePicker
模板本身的一部分。
试试这个:
<DatePicker>
<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}}}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DatePicker.Resources>
</DatePicker>
我意识到这个问题已经回答了很长时间了,但是直接绑定到 DatePicker 的 Text 属性将允许控件模板中的 TextBox 轻松遵循 DatePicker 提供的短/长格式。
<DatePicker>
<DatePicker.Resources>
<Style TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBox Text="{Binding Text, RelativeSource={RelativeSource AncestorType={x:Type DatePicker}}}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DatePicker.Resources>
</DatePicker>
“PART_TextBox”也不是必需的,因为它不是 DatePickerTextBox 模板的一部分。 DatePickerTextBox 包含的唯一部分是:
[TemplatePart(Name = DatePickerTextBox.ElementContentName, Type = typeof(ContentControl))]
public sealed partial class DatePickerTextBox : TextBox
private const string ElementContentName = "PART_Watermark";
并继承自TextBoxBase...
[TemplatePart(Name = "PART_ContentHost", Type = typeof(FrameworkElement))]
public abstract class TextBoxBase : Control
internal const string ContentHostTemplateName = "PART_ContentHost";
替代解决方案: 如果您选择不使用 TextBox 并使用继承的 PART,您将能够更改 DatePickerTextBox,而无需更改控件的默认功能。
<DatePicker>
<DatePicker.Resources>
<Style TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"/>
<ScrollViewer Name="PART_ContentHost"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DatePicker.Resources>
</DatePicker>
如果您在 XAML 中声明一个元素 (1),然后在
Design
视图中查看它,则可以右键单击 (2) 并导出其模板 (3):
1
<Window ...attributes...>
<Grid>
<DatePickerTextBox />
</Grid>
</Window>
2
3
<Style x:Key="DatePickerTextBoxStyle1" TargetType="{x:Type DatePickerTextBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePickerTextBox}">
<Grid>
<Grid.Resources>
<SolidColorBrush x:Key="WatermarkBrush" Color="#FFAAAAAA"/>
</Grid.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
<VisualTransition GeneratedDuration="0:0:0.1" To="MouseOver"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" To="#FF99C1E2" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="ContentElement"/>
<ColorAnimation Duration="0" To="#FF99C1E2" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="watermark_decorator"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="WatermarkStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Unwatermarked"/>
<VisualState x:Name="Watermarked">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentElement"/>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_Watermark"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisual"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="1" Opacity="1" Padding="{TemplateBinding Padding}">
<Grid x:Name="WatermarkContent" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Border x:Name="ContentElement" BorderBrush="#FFFFFFFF" BorderThickness="1"/>
<Border x:Name="watermark_decorator" BorderBrush="#FFFFFFFF" BorderThickness="1">
<ContentControl x:Name="PART_Watermark" Focusable="False" IsHitTestVisible="False" Opacity="0" Padding="2"/>
</Border>
<ScrollViewer x:Name="PART_ContentHost" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Border x:Name="FocusVisual" BorderBrush="#FF45D6FA" CornerRadius="1" IsHitTestVisible="False" Opacity="0"/>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>