具有自定义样式的WPF Inherited Datepicker将不允许将子项标记为

时间:2016-09-20 15:28:18

标签: .net wpf xaml inheritance mahapps.metro

我想创建一个自定义的DatePicker,而不是DatePickerTextBox,我用MaskedTextBox(来自WPFToolkit)替换它。无论出于何种原因,我都无法选中控件中的MaskedTextBox。相反,当项目被标记为“突出显示/聚焦”整个控件时,再次选项卡将转到下一个可用控件。

我希望能够在自定义控件之前处于控件之下,并且在选项卡时将焦点放在自定义控件中的MaskedTextBox上。

此控件取决于MahApps和WPFToolkit的存在。

Public Partial Class CustomMaskedDatePicker
Inherits DatePicker

Public Shared ReadOnly MaskedSelectedDateProperty As DependencyProperty = DependencyProperty.Register("MaskedSelectedDate", GetType(String), GetType(CustomMaskedDatePicker), New FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, AddressOf OnMaskedSelectedDateChanged))

Shared Sub New()
    DefaultStyleKeyProperty.OverrideMetadata(GetType(CustomMaskedDatePicker), New FrameworkPropertyMetadata(GetType(CustomMaskedDatePicker)))
End Sub

Private Shared Sub OnMaskedSelectedDateChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
    Dim tempDate As Date
    Dim selectedDate As Date? = DirectCast(d, CustomMaskedDatePicker).SelectedDate
    Dim tempDateString As String = e.NewValue

    If tempDateString = "" AndAlso IsNothing(DirectCast(d, CustomMaskedDatePicker).SelectedDate) Then Exit Sub

    If tempDateString = "" Then
        DirectCast(d, CustomMaskedDatePicker).SelectedDate = Nothing
        Exit Sub
    End If

    If tempDateString.Contains("_") Then
        DirectCast(d, CustomMaskedDatePicker).MaskedSelectedDate = If(IsNothing(selectedDate), "", String.Format("{0}{1}{2}", CDate(selectedDate).Month.ToString.PadLeft(2, "0"), CDate(selectedDate).Day.ToString.PadLeft(2, "0"), CDate(selectedDate).Year.ToString.PadLeft(4, "0")))
        Exit Sub
    End If

    If Not tempDateString.Contains("/") Then tempDateString = String.Format("{0}/{1}/{2}", tempDateString.Substring(0, 2), tempDateString.Substring(2, 2), tempDateString.Substring(4, 4))

    If Not Date.TryParse(tempDateString, tempDate) Then
        DirectCast(d, CustomMaskedDatePicker).MaskedSelectedDate = If(IsNothing(selectedDate), "", String.Format("{0}{1}{2}", CDate(selectedDate).Month.ToString.PadLeft(2, "0"), CDate(selectedDate).Day.ToString.PadLeft(2, "0"), CDate(selectedDate).Year.ToString.PadLeft(4, "0")))
        Exit Sub
    End If

    If IsNothing(selectedDate) OrElse selectedDate <> tempDate Then DirectCast(d, CustomMaskedDatePicker).SelectedDate = tempDate
End Sub

Public Property MaskedSelectedDate As String
    Get
        Return GetValue(MaskedSelectedDateProperty).ToString
    End Get
    Set
        SetValue(MaskedSelectedDateProperty, value.Replace("/", ""))
    End Set
End Property

Friend Const ElementMaskedTextBox As String = "PART_MaskedTextBox"

Protected Overrides Sub OnSelectedDateChanged(e As SelectionChangedEventArgs)
    MyBase.OnSelectedDateChanged(e)

    Dim dt As Date = CDate(e.AddedItems(0)).ToShortDateString()
    MaskedSelectedDate = String.Format("{0}{1}{2}", dt.Month.ToString.PadLeft(2, "0"), dt.Day.ToString.PadLeft(2, "0"), dt.Year.ToString.PadLeft(4, "0"))
End Sub 
End Class

XAML:

<ResourceDictionary
         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:local="clr-namespace:App"
         xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
         xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
         mc:Ignorable="d">

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
    <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
    <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
</ResourceDictionary.MergedDictionaries>

<Style TargetType="{x:Type local:CustomMaskedDatePicker}">
    <Setter Property="Foreground" Value="{DynamicResource TextBrush}" />
    <Setter Property="Background" Value="{DynamicResource ControlBackgroundBrush}" />
    <Setter Property="BorderBrush" Value="{DynamicResource TextBoxBorderBrush}" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="CalendarStyle" Value="{DynamicResource MetroCalendar}" />
    <Setter Property="controls:ControlsHelper.FocusBorderBrush" Value="{DynamicResource TextBoxFocusBorderBrush}" />
    <Setter Property="controls:ControlsHelper.MouseOverBorderBrush" Value="{DynamicResource TextBoxMouseOverBorderBrush}" />
    <Setter Property="controls:TextBoxHelper.IsMonitoring" Value="True" />
    <Setter Property="FontFamily" Value="{DynamicResource ContentFontFamily}" />
    <Setter Property="FontSize" Value="{DynamicResource ContentFontSize}" />
    <Setter Property="IsTodayHighlighted" Value="True" />
    <Setter Property="MinHeight" Value="26" />
    <Setter Property="Padding" Value="0" />
    <Setter Property="SelectedDateFormat" Value="Short" />
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="Validation.ErrorTemplate" Value="{DynamicResource ValidationErrorTemplate}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomMaskedDatePicker}">
                <Grid x:Name="PART_Root">
                    <Border x:Name="Base" 
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    <Grid x:Name="PART_InnerGrid" Margin="-5,0,0,0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>

                        <Button x:Name="PART_Button" 
                                Grid.Column="1"
                                Height="Auto"
                                Style="{DynamicResource ChromelessButtonStyle}"
                                Foreground="{TemplateBinding Foreground}"
                                IsTabStop="False"
                                HorizontalAlignment="Right"
                                Margin="0,2,2,2">
                            <ContentControl Style="{DynamicResource {x:Type ContentControl}}"
                                            Content="M34,52H31V38.5C29.66,39.9 28.16,40.78 26.34,41.45V37.76C27.3,37.45 28.34,36.86 29.46,36C30.59,35.15 31.36,34.15 31.78,33H34V52M45,52V48H37V45L45,33H48V45H50V48H48V52H45M45,45V38.26L40.26,45H45M18,57V23H23V20A2,2 0 0,1 25,18H29C30.11,18 31,18.9 31,20V23H45V20A2,2 0 0,1 47,18H51C52.11,18 53,18.9 53,20V23H58V57H18M21,54H55V31H21V54M48.5,20A1.5,1.5 0 0,0 47,21.5V24.5A1.5,1.5 0 0,0 48.5,26H49.5C50.34,26 51,25.33 51,24.5V21.5A1.5,1.5 0 0,0 49.5,20H48.5M26.5,20A1.5,1.5 0 0,0 25,21.5V24.5A1.5,1.5 0 0,0 26.5,26H27.5A1.5,1.5 0 0,0 29,24.5V21.5A1.5,1.5 0 0,0 27.5,20H26.5Z"
                                            Padding="0"
                                            Width="21"
                                            Height="16">
                                <ContentControl.Template>
                                    <ControlTemplate TargetType="{x:Type ContentControl}">
                                        <Viewbox Margin="{TemplateBinding Padding}">
                                            <Path Fill="{TemplateBinding Foreground}"
                                                Stretch="Uniform"
                                                Data="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay, Converter={local:xConNullToUnsetValueConverter}}"
                                                SnapsToDevicePixels="True"
                                                UseLayoutRounding="False" />
                                        </Viewbox>
                                    </ControlTemplate>
                                </ContentControl.Template>
                            </ContentControl>
                        </Button>

                        <DatePickerTextBox Grid.Column="0" x:Name="PART_TextBox" Visibility="Hidden" IsTabStop="False"/>
                        <xctk:MaskedTextBox x:Name="PART_MaskedTextBox" Style="{DynamicResource {x:Type TextBox}}"
                                            Grid.Column="0"
                                            HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                            VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                                            Foreground="{TemplateBinding Foreground}"
                                            Background="Transparent"
                                            FocusVisualStyle ="{x:Null}"
                                            FontFamily ="{DynamicResource ContentFontFamily}"
                                            FontSize="{DynamicResource ContentFontSize}"
                                            ScrollViewer.PanningMode="VerticalFirst"
                                            Stylus.IsFlicksEnabled="False"
                                            CaretBrush="{DynamicResource BlackBrush}"
                                            ContextMenu="{DynamicResource TextBoxMetroContextMenu}"
                                            Focusable="{TemplateBinding Focusable}"
                                            Mask="00/00/0000"
                                            Text="{Binding MaskedSelectedDate, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                                            BorderThickness="0"
                                            IsTabStop="True"/>
                    </Grid>
                    <Popup x:Name="PART_Popup"
                               AllowsTransparency="True"
                               Placement="Bottom"
                               PlacementTarget="{Binding ElementName=PART_Root}"
                               StaysOpen="False"/>
                    <Border x:Name="DisabledVisualElement"
                            Background="{DynamicResource ControlsDisabledBrush}"
                            BorderBrush="{DynamicResource ControlsDisabledBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Opacity="0"
                            IsHitTestVisible="False"
                            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />

                </Grid>

                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter TargetName="Base" Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:ControlsHelper.MouseOverBorderBrush)}" />
                    </Trigger>
                    <Trigger Property="IsFocused" Value="True" SourceName="PART_MaskedTextBox">
                        <Setter TargetName="Base" Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:ControlsHelper.FocusBorderBrush)}" />
                    </Trigger>
                    <Trigger Property="IsKeyboardFocusWithin" Value="True">
                        <Setter TargetName="Base" Property="BorderBrush" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(controls:ControlsHelper.FocusBorderBrush)}" />
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter TargetName="DisabledVisualElement" Property="Opacity" Value="0.6" />
                    </Trigger>
                    <Trigger SourceName="PART_Button" Property="IsMouseOver" Value="True">
                        <Setter TargetName="PART_Button" Property="Background" Value="{DynamicResource GrayBrush8}" />
                        <Setter TargetName="PART_Button" Property="Foreground" Value="{DynamicResource AccentColorBrush}" />
                    </Trigger>
                    <Trigger SourceName="PART_Button" Property="IsPressed" Value="True">
                        <Setter TargetName="PART_Button" Property="Background" Value="{DynamicResource BlackBrush}" />
                        <Setter TargetName="PART_Button" Property="Foreground" Value="{DynamicResource WhiteBrush}" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

1 个答案:

答案 0 :(得分:0)

通过在代码中覆盖OnGotFocus和OnGotKeyboardFocus来解决此问题。

<?php
//connect to mysql database
$connection = mysqli_connect("localhost","user","password","autocomplete_test")
or die("Error " . mysqli_error($connection));

//fetch data from database
$sql = "select distinct First_Name from data";
$result = mysqli_query($connection, $sql) or die("Error " . mysqli_error($connection));

?>
<!DOCTYPE html>
<html>
<head>
<title>Autocomplete Textbox in HTML5 PHP and MySQL</title>
</head>
<body>
<label for="fname">First Name</label>
<input type="text" list="firstname" autocomplete="off" id="fname">
<datalist id="firstname">
    <?php while($row = mysqli_fetch_array($result)) { ?>
        <option value="<?php echo $row['First_Name']; ?>"><?php echo $row['First_Name']; ?></option>
    <?php } ?>
</datalist>
<?php mysqli_close($connection); ?>
</body>
</html>