Reputation: 383
Tried a lot of stuff, still doesn't work. Binding on the two TextBlocks don't work. Used INotifyPropertyChanged
interface much like this code to no avail.
Code:
MainWindow.xaml:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ClockWatcher" xmlns:System="clr-namespace:System;assembly=mscorlib"
x:Name="clockWatcherWindow"
x:Class="ClockWatcher.MainWindow"
Title="Clock Watcher" Height="554" Width="949"
KeyDown="KeysDown" Focusable="True" Closing="SaveSession"
DataContext="{Binding SM, RelativeSource={RelativeSource Self}}">
<TextBlock x:Name="programStartBlock" Text="{Binding StartTime, BindsDirectlyToSource=True, FallbackValue=Binding sucks so much!!!, StringFormat=ProgramStarted: \{0\}, TargetNullValue=This thing is null}" Padding="{DynamicResource labelPadding}" FontSize="{DynamicResource fontSize}"/>
<TextBlock x:Name="totalTimeLabel" Text="{Binding SM.currentSession.TotalTime, StringFormat=Total Time: \{0\}}" Padding="{DynamicResource labelPadding}" FontSize="{DynamicResource fontSize}"/>
</Window>
MainWindow.xaml.cs:
public partial class MainWindow : Window
{
private const string SESSION_FILENAME = "SessionFiles.xml";
/// <summary>
/// Represents, during selection mode, which TimeEntry is currently selected.
/// </summary>
public SessionManager SM { get; private set; }
public MainWindow()
{
InitializeComponent();
SM = new SessionManager();
SM.newAddedCommentEvent += currentTimeEntry_newComment;
SM.timeEntryDeletedEvent += currentTimeEntry_delete;
SM.commentEntryDeletedEvent += entry_delete;
}
}
SessionManager.cs:
public class SessionManager : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[NonSerialized]
private DateTime _dtStartTime;
private Session current_session;
#region Properties
public DateTime StartTime
{
get
{
return _dtStartTime;
}
private set
{
if (_dtStartTime != value)
{
_dtStartTime = value;
OnPropertyChanged("StartTime");
}
}
}
public Session CurrentSession
{
get
{
return current_session;
}
set
{
if (current_session != value)
{
OnPropertyChanged("CurrentSession");
current_session = value;
}
}
}
#endregion
public SessionManager()
{
_dtStartTime = DateTime.Now;
}
private void OnPropertyChanged([CallerMemberName] string member_name = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(member_name));
}
}
}
Session.cs:
public class Session : INotifyPropertyChanged
{
private TimeSpan total_time;
public DateTime creationDate { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
public TimeSpan TotalTime
{
get
{
return total_time;
}
set
{
if (total_time != value)
{
OnPropertyChanged("TotalTime");
total_time = value;
}
}
}
public Session()
{
creationDate = DateTime.Now;
}
private void OnPropertyChanged([CallerMemberName] string member_name = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(member_name));
}
}
}
Upvotes: 0
Views: 559
Reputation: 1669
The marked correct answer is definitely the better way to do it, but I just wanted to answer explaining more in detail why what you posted didn't work.
The issue is that when you wrote DataContext={Binding SM, RelativeSource={RelativeSource Self}
in your MainWindow.xaml, the binding was evaluted before your line SM = new SessionManager();
was executed in your MainWindow.xaml.cs constructor.
You can see this in effect if you changed your getter for SM to:
public SessionManager SM
{
get { return new SessionManager();}
}
This basically ensures that when WPF evaluates your binding, it'll get an actual object for your SM property instead of null.
Just thought perhaps this will help understanding and reduce frustration next time :). The way you asked your question, you technically needed to implement INotifyPropertyChanged on your MainWindow class, which is a big no-no.
Upvotes: 0
Reputation: 9827
In first TextBlock, instead of SM.StartTime, write only StartTime.
Remove ElementName from first TB.
Make CurrentSession public property, Your currentSession is private now.
In your SessionManager ctor, current_session = new Session();
Remove DataContext from XAML, use this.DataContext = SM;
in your window contructor.
If you want to use DataContext in XAML,
<Window.DataContext>
<local:SessionManager />
</Window.DataContext>
Upvotes: 2