【问题标题】:Custom WPF DatePickerTextBox Template自定义 WPF DatePickerTextBox 模板
【发布时间】:2011-04-07 20:53:09
【问题描述】:

我正在尝试在DatePicker 控件中使用自定义TextBox,但我无法将弹出日历中的日期绑定到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 模板本身的一部分。

请有人帮忙! :)

提前致谢!

【问题讨论】:

    标签: .net wpf xaml datepicker textbox


    【解决方案1】:

    试试这个:

    <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>
    

    【讨论】:

    • 明白了。非常感谢!
    • 我有一个问题:它不支持默认模板所做的短/长日期格式。
    • @dex3707 您可以将 StringFormat 添加到 Textbinding 并指定格式,例如
    【解决方案2】:

    我意识到这个问题已经回答了很长时间了,但是直接绑定到 DatePicker 的 Text 属性将允许您的控件模板中的 TextBox 轻松实现由 @987654323 提供的短/长格式@。

    <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 包含的唯一 PART 是:

    [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>
    

    【讨论】:

    • 我已经在这上面花费了几个小时,然后我发现你的答案隐藏在大量的问题和答案中。你的是最好的实现。好东西!
    【解决方案3】:

    如果您在 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>
    

    【讨论】:

    • 感谢您提供的超级有用的提示:D。
    猜你喜欢
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-07
    相关资源
    最近更新 更多