Пользовательский шаблон WPF DatePickerTextBox

Я пытаюсь использовать пользовательский TextBox на DatePicker control, но я не могу получить дату привязки из всплывающего календаря к 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 шаблон себя.

кто-нибудь, пожалуйста, помогите! :)

спасибо заранее!

3 ответов


попробуйте это:

<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 ' S Text свойство позволит поле в вашем шаблоне управления, чтобы легко соблюдать короткий / длинный формат, предоставляемый 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";

Альтернативное Решение: Если вы откажетесь от использования поле и использовать унаследованную часть вы сможете изменить 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 view, вы можете щелкнуть правой кнопкой мыши (2) и экспортировать его шаблон (3):

1

<Window ...attributes...>
    <Grid>
        <DatePickerTextBox />
    </Grid>
</Window>

2

enter image description here

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>