Data Binding with Timer Implementation

2019-06-13 19:09发布

问题:

Can't figure out why this timer isn't displaying information. Timer rigged to method to update TextBlock in TimeEntry. Binding doesn't seem to work, and I don't understand how to do it properly. I've looked at the MSDN sites. They only give out the basics: not enough.

Code:

TimeEntry.xaml.cs:

public partial class TimeEntry : UserControl
{
    public static readonly DependencyProperty timeSpentProperty =
       DependencyProperty.Register("timeSpent", typeof(TimeSpan),
       typeof(TimeEntry),
       new FrameworkPropertyMetadata(TimeSpan.Zero));

    #region Properties
    public TimeSpan timeSpent
    {
        get
        {
            return (TimeSpan)GetValue(TimeEntry.timeSpentProperty);
        }
        set
        {
            SetValue(TimeEntry.timeSpentProperty, value);
        }
    }
    #endregion

    static TimeEntry() { }

    public TimeEntry(int id)
    {
        DataContext = this;
        this.InitializeComponent();
        //code
    }
}

TimeEntry.xaml:

<UserControl
    x:Class="ClockWatcher.TimeEntry"
    x:Name="UserControl">
    <Grid x:Name="LayoutRoot" HorizontalAlignment="Left"
        VerticalAlignment="Top" Width="{DynamicResource creationWidth}"
        Height="{DynamicResource creationHeight}">
        <TextBlock x:Name="timeSpentBlock"
            HorizontalAlignment="Left" TextWrapping="Wrap"
            Text="{Binding timeSpent, ElementName=UserControl}"
            VerticalAlignment="Top" Padding="{StaticResource labelPadding}"/>       
    </Grid>
</UserControl>

SessionManager.cs:

    public class SessionManager : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        [NonSerialized]
        private Timer _timer;
        [NonSerialized]
        private Stopwatch _clockWatch;
        [NonSerialized]
        private DateTime _dtStartTime;
        private Session current_session;
        public string strStartTime
        {
            get
            {
                return _dtStartTime.ToString();
            }
            private set { }
        }

        public SessionManager()
        {
            _clockWatch = new Stopwatch();
            _timer = new Timer(1000);//one second
            _timer.Elapsed += clockWatch_Elapsed;
            _dtStartTime = DateTime.Now;
            CurrentSession = new Session();
        }

        /// <summary>
        /// Registered to Timer.Elapsed Event
        /// (See constructor)
        /// </summary>
        public void clockWatch_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (CurrentSession != null)
            {
                //update the timespent variable of the current timeEntry
                if (CurrentSession.currentTimeEntry != null)
                {
                    CurrentSession.currentTimeEntry.timeSpent = _clockWatch.Elapsed;
                    calculateTotalTime();
                }
            }
        }
        private void OnPropertyChanged([CallerMemberName] string member_name = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(member_name));
            }
        }
    }

回答1:

You must change like this. Because you doing wrong way.

  1. Think about it, which property must update. Your wanted property is timeSpent. Then your TimeEntry class must implement INotifyPropertyChanged event.

  2. timeSpent property no need to Dependency Property. Because you assign it manually in 'elapsed' event.

  3. Your xaml must be connected with your class. In other words, your body(xaml) must have soul(class instance).

  4. You already bind model in step 3. Now you simple bind like this.

Explanation of step 2. (Dependency Property)

Your current usage is manually assignment. In your case no need dependency property

If you want to use like below image, Your property timeSpent must Dependency Property.