Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/PerfView/EventViewer/EventWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@
<MenuItem Header="_Close" Click="DoClose"/>
</MenuItem>
<MenuItem Header="_View">
<MenuItem Header="_Show Local Time" IsCheckable="True" IsChecked="False" Checked="DoUseLocalTime" Unchecked="DoUseOriginTime"/>
<MenuItem x:Name="ShowTimeStampColumnsMenuItem" Header="Show _TimeStamp Columns" IsCheckable="True" IsChecked="True" Checked="DoShowTimeStampColumns" Unchecked="DoHideTimeStampColumns"/>
<MenuItem x:Name="ShowLocalTimeMenuItem" Header="_Show Local Time" IsCheckable="True" IsChecked="False" Checked="DoUseLocalTime" Unchecked="DoUseOriginTime"/>
</MenuItem>
<MenuItem Header="_Help">
<MenuItem Header="_Help on Event Viewer" Command="Help" CommandParameter="EventViewerQuickStart" />
Expand Down
95 changes: 88 additions & 7 deletions src/PerfView/EventViewer/EventWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ public EventWindow(EventWindow template)
{
selection.Add(item);
}

// Copy timestamp column visibility settings from template
ShowTimeStampColumnsMenuItem.IsChecked = template.ShowTimeStampColumnsMenuItem.IsChecked;
ShowLocalTimeMenuItem.IsChecked = template.ShowLocalTimeMenuItem.IsChecked;
ShowLocalTimeMenuItem.IsEnabled = template.ShowLocalTimeMenuItem.IsEnabled;

Update();
}
public EventWindow(Window parent, PerfViewEventSource data)
Expand Down Expand Up @@ -167,6 +173,26 @@ public EventWindow(Window parent, PerfViewEventSource data)
};

MultiLineViewPaneHidden = (App.UserConfigData["MultiLineViewPaneHidden"] == "true");

// Initialize timestamp column visibility based on user preference
bool showTimeStampColumns = App.UserConfigData["EventWindowShowTimeStampColumns"] != "false"; // Default to true
ShowTimeStampColumnsMenuItem.IsChecked = showTimeStampColumns;
if (!showTimeStampColumns)
{
// Hide both timestamp columns and disable the timezone menu
foreach (var column in Grid.Columns)
{
if (column == OriginTimeStampColumn || column == LocalTimeStampColumn)
{
column.Visibility = Visibility.Hidden;
}
}
ShowLocalTimeMenuItem.IsEnabled = false;
}
else
{
ShowLocalTimeMenuItem.IsEnabled = true;
}
}

public PerfViewEventSource DataSource { get; private set; }
Expand Down Expand Up @@ -1893,32 +1919,87 @@ private void Add(ObservableCollection<EventRecord> events, EventRecord event_)

private void DoUseLocalTime(object sender, RoutedEventArgs e)
{
foreach (var i in Grid.Columns)
// Only change visibility if timestamp columns are enabled
if (ShowTimeStampColumnsMenuItem.IsChecked)
{
if (i == OriginTimeStampColumn)
foreach (var i in Grid.Columns)
{
i.Visibility = Visibility.Hidden;
if (i == OriginTimeStampColumn)
{
i.Visibility = Visibility.Hidden;
}
else if (i == LocalTimeStampColumn)
{
i.Visibility = Visibility.Visible;
}
}
else if (i == LocalTimeStampColumn)
}
}

private void DoUseOriginTime(object sender, RoutedEventArgs e)
{
// Only change visibility if timestamp columns are enabled
if (ShowTimeStampColumnsMenuItem.IsChecked)
{
foreach (var i in Grid.Columns)
{
i.Visibility = Visibility.Visible;
if (i == OriginTimeStampColumn)
{
i.Visibility = Visibility.Visible;
}
else if (i == LocalTimeStampColumn)
{
i.Visibility = Visibility.Hidden;
}
}
}
}

private void DoUseOriginTime(object sender, RoutedEventArgs e)
private void DoShowTimeStampColumns(object sender, RoutedEventArgs e)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When testing there is a NullReferenceException thrown by this method:

System.NullReferenceException: Object reference not set to an instance of an object.
   at PerfView.EventWindow.DoShowTimeStampColumns(Object sender, RoutedEventArgs e)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.Controls.MenuItem.OnIsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
   at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
   at System.Windows.Baml2006.WpfKnownMemberInvoker.SetValue(Object instance, Object value)
   at MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(Object inst, XamlMember property, Object value)
   at MS.Internal.Xaml.Runtime.PartialTrustTolerantRuntime.SetValue(Object obj, XamlMember property, Object value)
   at System.Xaml.XamlObjectWriter.Logic_ApplyPropertyValue(ObjectWriterContext ctx, XamlMember prop, Object value, Boolean onParent)
   at System.Xaml.XamlObjectWriter.Logic_DoAssignmentToParentProperty(ObjectWriterContext ctx)
   at System.Xaml.XamlObjectWriter.WriteEndMember()
   at System.Windows.Markup.WpfXamlLoader.TransformNodes(XamlReader xamlReader, XamlObjectWriter xamlWriter, Boolean onlyLoadOneNode, Boolean skipJournaledProperties, Boolean shouldPassLineNumberInfo, IXamlLineInfo xamlLineInfo, IXamlLineInfoConsumer xamlLineInfoConsumer, XamlContextStack`1 stack, IStyleConnector styleConnector)
   at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
   at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
   at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
   at PerfView.EventWindow..ctor(Window parent, PerfViewEventSource data)
   at PerfView.PerfViewEventSource.<>c__DisplayClass15_0.<Open>b__1()
   at PerfView.StatusBar.<>c__DisplayClass23_0.<EndWork>b__0()
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the NullReferenceException by adding null checks in both DoShowTimeStampColumns and DoHideTimeStampColumns methods. The issue occurred because these event handlers were being triggered during XAML initialization when UI elements weren't fully constructed yet. Commit 6399125.

{
// Check if UI elements are initialized to avoid null reference during XAML construction
if (ShowLocalTimeMenuItem == null || Grid?.Columns == null)
return;

// Show the appropriate timestamp column based on current preference
bool useLocalTime = ShowLocalTimeMenuItem.IsChecked;
foreach (var i in Grid.Columns)
{
if (i == OriginTimeStampColumn)
{
i.Visibility = Visibility.Visible;
i.Visibility = useLocalTime ? Visibility.Hidden : Visibility.Visible;
}
else if (i == LocalTimeStampColumn)
{
i.Visibility = useLocalTime ? Visibility.Visible : Visibility.Hidden;
}
}
// Enable the Show Local Time menu item
ShowLocalTimeMenuItem.IsEnabled = true;

// Save preference
App.UserConfigData["EventWindowShowTimeStampColumns"] = "true";
}

private void DoHideTimeStampColumns(object sender, RoutedEventArgs e)
{
// Check if UI elements are initialized to avoid null reference during XAML construction
if (ShowLocalTimeMenuItem == null || Grid?.Columns == null)
return;

// Hide both timestamp columns
foreach (var i in Grid.Columns)
{
if (i == OriginTimeStampColumn || i == LocalTimeStampColumn)
{
i.Visibility = Visibility.Hidden;
}
}
// Gray out (disable) the Show Local Time menu item
ShowLocalTimeMenuItem.IsEnabled = false;

// Save preference
App.UserConfigData["EventWindowShowTimeStampColumns"] = "false";
}
}
}