UWP - 如何在 TimePicker_TimeChanged 中格式化时间并在 TimepickerFlyout 中选择没有按钮的时间 [英] UWP - How to format time in TimePicker_TimeChanged AND Select Time without Buttons inside in TimepickerFlyout

查看:25
本文介绍了UWP - 如何在 TimePicker_TimeChanged 中格式化时间并在 TimepickerFlyout 中选择没有按钮的时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发 UWP 应用程序 (Win10 VS2015).我有两个问题.

I am developing UWP App (Win10 VS2015). I have two problems.

1- 如何以 12 小时格式获取此格式的时间(下午 4:00 或上午 9:34 等),我可以通过此获取没有 PM/AM 的值TimePicker.Time = sender.Time.ToString(@"hh\:mm"),但我需要我提到的实际格式.

1- How can I get the time in this format (4:00 PM or 9:34 AM etc..) in 12hours format, I can get the value without PM/AM via this TimePicker.Time = sender.Time.ToString(@"hh\:mm"), but I need the actual format as I mentioned.

XAML 代码

<TimePicker ClockIdentifier="12HourClock" TimeChanged="TimePicker_TimeChanged" Style="{StaticResource TimePickerStyleCustom}"/>

.cs 代码

private void TimePicker_TimeChanged(object sender, TimePickerValueChangedEventArgs e)
    {            
        timeTitle.Text = (sender as TimePicker).Time.ToString(@"hh\:mm");
    }

通过上面的代码,我可以在没有 AM/PM 的情况下获取值,而且它是 24 小时格式,即 4:00PM 是 16:00,但我需要它在 4:00PM 或 4:00AM(这只是一个例子).如果我把 .ToString(@"hh\:mm tt"); 它抛出异常.请问如何得到这个.

Via the above code, I can get the value without AM/PM and also it is in 24hour format i.e. 4:00PM is in 16:00, but I need it in 4:00PM or 4:00AM (this is just an example). If I put .ToString(@"hh\:mm tt"); it throws exception. How to get this please.

2- 第二个问题是,当我们点击 Timepicker 时,一个 TimePickerFlyout 会展开,我们通过点击小时/分钟来选择时间,最后点击(勾号)标记选择时间...但我需要删除这些按钮(完成 (_/) 和取消 (X))并通过在弹出面板中选择小时/分钟而不是单击按钮并将其分配给字符串来选择时间.我可以从 TimePickerFlyoutPresenter 样式中删除按钮,但是如何使选择功能像按钮单击一样.

2- 2nd problem is, When we tap on the Timepicker, a TimePickerFlyout expands and we select time by clicking on hours/minutes and when finalize then click on the (Tick) Mark to select Time ... but I need to remove these buttons (Done (_/) & Cancel (X)) and select time by selecting the Hour/Min in Flyout panel rather than button click and assign it to a string. I can remove the buttons from TimePickerFlyoutPresenter Style but then how to make the Selection functional like button click.

请看截图,第一部分有 2 个按钮可用并且可以正常工作,但我需要第二部分,如右侧所示.

See the screenshot, in first portion the 2 buttons are available and it worked, but I need the 2nd portion as shown in the right side.

推荐答案

对于第一个问题TimeSpan 表示时间间隔而不是一天中的时间.您必须将其转换为 DateTime 然后对其进行格式化

For First problem TimeSpan represents a time interval not a time of day. You have to convert it to DateTime then format it

 private void TestTimePicker_TimeChanged(object sender, TimePickerValueChangedEventArgs e)
        {
          string Text = (sender as TimePicker).Time.ToString(@"hh\:mm");
            var dateTime = new DateTime((sender as TimePicker).Time.Ticks); // Date part is 01-01-0001
            var formattedTime = dateTime.ToString("h:mm tt", CultureInfo.InvariantCulture);
        }

问题 2为此,您必须从 PickerFlyoutBase 或 Flyout 实现自己的 TimerPickerFlyout.这有点复杂,我还没有研究过.您可以观看此链接

Problem 2 For this either you have to implement your own TimerPickerFlyout from PickerFlyoutBase or from Flyout. It is bit complicated and I havent worked on that. You can watch this link for that

有一个简单的解决方法.正如您所提到的,您必须编辑 TimePickerFlyoutPresenter 样式.

There is a easy workaround . As you mentioned in question you have to edit TimePickerFlyoutPresenter style.

我尝试将 Tapped 事件处理程序添加到 FirstPickerHost、SecondPickerHost、ThirdPickerHost.但是您无法在 app.xaml 中添加事件处理程序.所以我使用了 Behavioral SDK 的交互.如果您的项目中使用了 Template10,则无需下载任何内容,只需在 app.xaml 中添加以下命名空间

I tried adding Tapped event handler to FirstPickerHost,SecondPickerHost,ThirdPickerHost.But you cant add event handlers in app.xaml. So i used Behavioural SDK's interactions. If you have Template10 used in your project you dont have to download anything just add following namespaces in app.xaml

xmlns:interact="using:Microsoft.Xaml.Interactivity" 
xmlns:interactcore="using:Microsoft.Xaml.Interactions.Core"



 <Style TargetType="TimePickerFlyoutPresenter">
        <Setter Property="Width" Value="242" />
        <Setter Property="MinWidth" Value="242" />
        <Setter Property="MaxHeight" Value="396" />
        <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
        <Setter Property="FontWeight" Value="Normal" />
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="Background" Value="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}" />
        <Setter Property="AutomationProperties.AutomationId" Value="TimePickerFlyoutPresenter" />
        <Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}" />
        <Setter Property="BorderThickness" Value="{ThemeResource DateTimeFlyoutBorderThickness}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="TimePickerFlyoutPresenter">
                    <Border x:Name="Background"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        MaxHeight="396">
                        <Grid x:Name="ContentPanel">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="*" />
                           </Grid.RowDefinitions>

                            <Grid >
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" x:Name="FirstPickerHostColumn" />
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="*" x:Name="SecondPickerHostColumn" />
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="*" x:Name="ThirdPickerHostColumn" />
                                </Grid.ColumnDefinitions>

                                <Rectangle x:Name="HighlightRect" Fill="{ThemeResource SystemControlHighlightListAccentLowBrush}" Grid.Column="0" Grid.ColumnSpan="5" VerticalAlignment="Center" Height="44"  >

                                </Rectangle>

                                <Border x:Name="FirstPickerHost" Grid.Column="0" >
                                    <interact:Interaction.Behaviors>
                                        <interactcore:EventTriggerBehavior EventName="Tapped">
                                            <interactcore:InvokeCommandAction Command="{Binding ClosePopUp}"/>
                                        </interactcore:EventTriggerBehavior>
                                    </interact:Interaction.Behaviors>
                                </Border>
                                <Rectangle x:Name="FirstPickerSpacing" Fill="{ThemeResource SystemControlForegroundBaseLowBrush}" HorizontalAlignment="Center" Width="2" Grid.Column="1" >

                                </Rectangle>
                                <Border x:Name="SecondPickerHost" Grid.Column="2" >
                                    <interact:Interaction.Behaviors>
                                        <interactcore:EventTriggerBehavior EventName="Tapped">
                                            <interactcore:InvokeCommandAction Command="{Binding ClosePopUp}"/>
                                        </interactcore:EventTriggerBehavior>
                                    </interact:Interaction.Behaviors>
                                </Border>
                                <Rectangle x:Name="SecondPickerSpacing" Fill="{ThemeResource SystemControlForegroundBaseLowBrush}" HorizontalAlignment="Center" Width="2" Grid.Column="3" >

                                </Rectangle>
                                <Border x:Name="ThirdPickerHost" Grid.Column="4" >
                                    <interact:Interaction.Behaviors>
                                        <interactcore:EventTriggerBehavior EventName="Tapped">
                                            <interactcore:InvokeCommandAction Command="{Binding ClosePopUp}"/>
                                        </interactcore:EventTriggerBehavior>
                                    </interact:Interaction.Behaviors>
                                </Border>

                            </Grid>

                            <Grid Grid.Row="1"  Visibility="Collapsed">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>
                                <Rectangle Height="2" VerticalAlignment="Top" Fill="{ThemeResource SystemControlForegroundBaseLowBrush}" Grid.ColumnSpan="2" />

                                <Button x:Name="AcceptButton" Grid.Column="0" Content="&#xE8FB;" FontFamily="{ThemeResource SymbolThemeFontFamily}" FontSize="16" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Style="{StaticResource DateTimePickerFlyoutButtonStyle}" Margin="0,2,0,0" />
                                <Button x:Name="DismissButton" Grid.Column="1" Content="&#xE711;" FontFamily="{ThemeResource SymbolThemeFontFamily}" FontSize="16" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Style="{StaticResource DateTimePickerFlyoutButtonStyle}" Margin="0,2,0,0" />
                            </Grid>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

并且您必须将 Timepicker 的数据上下文设置为您的视图模型.

And you have to set datacontext of Timepicker to your viewmodel.

   <TimePicker x:Name="TestTimePicker" Time="{Binding SelectedTime,Mode=TwoWay}" ClockIdentifier="12HourClock" Time="0" TimeChanged="TestTimePicker_TimeChanged" >
     </TimePicker>

    public MainPage()
            {
                this.InitializeComponent();
                DataContext = new TestViewModel();
                TestTimePicker.DataContext = this.DataContext;
            }

    public class TestViewModel:INotifyPropertyChanged
        {
            public DelegateCommand<TappedRoutedEventArgs> ClosePopUp { get; set; }
 TimeSpan selectedTime;
        public TimeSpan SelectedTime
        { get { return selectedTime; }
            set
            {
                if (value != selectedTime)
                {
                    selectedTime = value;
                    OnPropertyChanged("SelectedTime");
                }
            }
        }

            public TestViewModel()
        {

            ClosePopUp = new DelegateCommand<TappedRoutedEventArgs>((args) =>
            {
                if (args.OriginalSource is Grid)
                {
                    Grid grid = args.OriginalSource as Grid;
                    if (grid != null)
                    {
                       var fly = FlyoutBase.GetAttachedFlyout(grid);
                        var flyoutpresenter = FindParent<TimePickerFlyoutPresenter>(grid);
                        if (flyoutpresenter != null)
                            (flyoutpresenter.Parent as Popup).IsOpen = false;
                       var firstPicker= FindParent(grid,"FirstPickerHost");
                        var secondPicker = FindParent(grid, "SecondPickerHost");
                        var thirdPicker = FindParent(grid, "ThirdPickerHost");
                        var textblock = FindElementInVisualTree<TextBlock>(grid);
                        if (firstPicker != null)
                        {
                            SelectedTime = new TimeSpan(int.Parse(textblock.Text), SelectedTime.Minutes, SelectedTime.Seconds);

                        }
                         if(secondPicker!=null)
                        {
                            SelectedTime = new TimeSpan(SelectedTime.Hours, int.Parse(textblock.Text), SelectedTime.Seconds);
                        }
                        if (thirdPicker != null)
                        {
                          // AM/PM
                        }

                    }
                }
                else if(args.OriginalSource is TextBlock)
                {
                    TextBlock textblock = args.OriginalSource as TextBlock;
                    if (textblock != null)
                    {
                        var fly = FlyoutBase.GetAttachedFlyout(textblock);
                        var flyoutpresenter = FindParent<TimePickerFlyoutPresenter>(textblock);
                        if (flyoutpresenter != null)
                            (flyoutpresenter.Parent as Popup).IsOpen = false;
                        var firstPicker = FindParent(textblock, "FirstPickerHost");
                        var secondPicker = FindParent(textblock, "SecondPickerHost");
                        var thirdPicker = FindParent(textblock, "ThirdPickerHost");

                        if (firstPicker != null)
                        {
                            SelectedTime = new TimeSpan(int.Parse(textblock.Text), SelectedTime.Minutes, SelectedTime.Seconds);

                        }
                        if (secondPicker != null)
                        {
                            SelectedTime = new TimeSpan(SelectedTime.Hours, int.Parse(textblock.Text), SelectedTime.Seconds);
                        }
                        if (thirdPicker != null)
                        {
                           //  AM/PM
                        }
                    }
                }
                else
                {

                }
            });

        }

        public event PropertyChangedEventHandler PropertyChanged;
        void OnPropertyChanged(string propertyName)
        {
            // the new Null-conditional Operators are thread-safe:
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private T FindParent<T>(DependencyObject child) where T : DependencyObject
        {
            var parent = VisualTreeHelper.GetParent(child);
            if (parent != null && parent is T)
                return (T)parent;
            else if (parent == null)
                return null;
            else
            {
                var result = FindParent<T>(parent);
                if (result != null)
                    return result;

            }
            return null;
        }
        private DependencyObject FindParent(DependencyObject child,string parentName) 
        {
            var parent = VisualTreeHelper.GetParent(child);
            if (parent != null && (parent as FrameworkElement).Name.Equals(parentName))
                return parent;
            else if (parent == null)
                return null;
            else
            {
                var result = FindParent(parent,parentName);
                if (result != null)
                    return result;

            }
            return null;
        }
       private T FindElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject
    {
        var count = VisualTreeHelper.GetChildrenCount(parentElement);
        if (count == 0) return null;

        for (int i = 0; i < count; i++)
        {
            var child = VisualTreeHelper.GetChild(parentElement, i);
            if (child != null && child is T)
                return (T)child;
            else
            {
                var result = FindElementInVisualTree<T>(child);
                if (result != null)
                    return result;
            }
        }
        return null;
    }
    }

我上面在 ClosePopUp 命令中所做的是使用 VisualTreeHelper getparaent() 方法以编程方式查找 TimePickerFlyoutPresenterTimePickerFlyoutPresenter 父项是一个 PopUp,实际上是您的 TimePickerFlyout.将弹出窗口的 IsOpen 设置为 false

What i'm doing above in ClosePopUp command is programmatically finding TimePickerFlyoutPresenter using VisualTreeHelper getparaent() method TimePickerFlyoutPresenter parent is a PopUp that is actually your TimePickerFlyout. Set popup's IsOpen to false

// Updated the code to reflect selected hour and minute in timepicker. One issue left is update the selected AM or PM. I ll update if i get the solution

这是解决所有问题的完整项目的链接源代码

Here is a link to complete project which solves all issues Source Code

这篇关于UWP - 如何在 TimePicker_TimeChanged 中格式化时间并在 TimepickerFlyout 中选择没有按钮的时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆