Visual Studio / WPF > ObjectDataProvider > JSTとUTCの表示 > Provider.Refresh() | イベントの追加 | DateTime.Now.ToLongTimeString()


動作環境
Windows 7 Pro (32bit)
Microsoft Visual Studio 2017 Community

http://gushwell.ldblog.jp/archives/52333863.html
を元に学習中。

以下のように変更してみた。

  • UTC用のProviderを追加
  • DateTime.UtcNowを使ってUTCの表示
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace _170608_t1300_timer
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            MyClock myClock = this.Resources["keyMyClock"] as MyClock;
            myClock.ProviderJST = this.Resources["keyNowTime"] as ObjectDataProvider;
            myClock.ProviderUTC = this.Resources["keyUtcTime"] as ObjectDataProvider;
        }
    }
    public class MyClock
    {
        private System.Timers.Timer _timer = new System.Timers.Timer();
        public ObjectDataProvider ProviderJST { get; set; }
        public ObjectDataProvider ProviderUTC { get; set; }
        public MyClock()
        {
            _timer.Interval = 1000; // msec
            _timer.Elapsed += _timer_Elapsed; // イベント追加
            _timer.Enabled = true;
        }
        private void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            ProviderJST.Refresh();
            ProviderUTC.Refresh();
        }
        public string NowTime()
        {
            return "JST:" + DateTime.Now.ToLongDateString() + DateTime.Now.ToLongTimeString();
        }
        public string UtcTime()
        {
            return "UTC:" + DateTime.UtcNow.ToLongDateString() + DateTime.UtcNow.ToLongTimeString();                
        }
    }
}
MainWindow.xaml
<Window x:Class="_170608_t1300_timer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_170608_t1300_timer"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:MyClock x:Key="keyMyClock" />
        <ObjectDataProvider MethodName="NowTime" x:Key="keyNowTime"
                            ObjectInstance="{StaticResource keyMyClock}"/>
        <ObjectDataProvider MethodName="UtcTime" x:Key="keyUtcTime"
                            ObjectInstance="{StaticResource keyMyClock}"/>
    </Window.Resources>
    <Grid DataContext="{Binding Source={StaticResource keyNowTime}}">
        <StackPanel Margin="20">
            <TextBlock Height="28" Name="textJST" FontSize="18"
            Text="{Binding Source={StaticResource keyNowTime}}"/>
            <TextBlock Height="28" Name="textUTC" FontSize="18"
            Text="{Binding Source={StaticResource keyUtcTime}}"/>
        </StackPanel>
    </Grid>
</Window>

はまった点

写経するなかでXAMLにて以下の間違いをしたことで時計が表示されなかった。

        <ObjectDataProvider MethodName="NowTime" x:Key="keyNowTime"
                            ObjectInstance="={StaticResource keyMyClock}"/>

正しくは以下。

        <ObjectDataProvider MethodName="NowTime" x:Key="keyNowTime"
                            ObjectInstance="{StaticResource keyMyClock}"/>

{StaticResourceの前に余分な=を入力してしまっていた。

関連リンク

[XAML/C#] WPF でタイマーを使うには (Windows フォームから WPF へ)
https://code.msdn.microsoft.com/windowsdesktop/XAMLCVB-WPF-Windows-WPF-2aab6085

v0.2

XAMLを変更。

MainWindow.xaml
<Window x:Class="_170608_t1300_timer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_170608_t1300_timer"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:MyClock x:Key="keyMyClock" />
        <ObjectDataProvider MethodName="NowTime" x:Key="keyNowTime"
                            ObjectInstance="{StaticResource keyMyClock}"/>
        <ObjectDataProvider MethodName="UtcTime" x:Key="keyUtcTime"
                            ObjectInstance="{StaticResource keyMyClock}"/>
    </Window.Resources>
    <!--<Grid DataContext="{Binding Source={StaticResource keyNowTime}}">-->
    <Grid>
        <StackPanel Margin="20">
            <TextBlock Height="28" Name="textJST" FontSize="18"
            Text="{Binding Source={StaticResource keyNowTime}}"/>
            <TextBlock Height="28" Name="textUTC" FontSize="18"
            Text="{Binding Source={StaticResource keyUtcTime}}"/>
        </StackPanel>
    </Grid>
</Window>

GridにBindingしなくてもいいようだ。
(元記事のコメント欄に不要であることが記載されていた)。