فهرست منبع

+ Added IsCurrentTop read-only property to Gui.Toplevel class to allow a more convenient checking if a view's instance is currently on top (active and displayed).
- Fixed an elusive crash that may occur in the Application.RunLoop method due to a null'ed Toplevel.NeedDisplay property. This issue appears to be caused by a race condition that may occur when switching Views (TopLevel) too fast. Extended to all other NeedDisplay checks too.
- ListView control now displays empty rows for Null items in its Items collection, instead of crashing with a NullReferenceException.
- Improved MenuBarItem constructor behaviour by performing an additional sanity check on the MenuItem[] children parameter to ensure its not null. If so, raise an ArgumentNullException. Using an empty array of type MenuItem for this parameter still displays an empty menu as intended.

Fabian R 5 سال پیش
والد
کامیت
f2e5b08a88
3فایلهای تغییر یافته به همراه28 افزوده شده و 12 حذف شده
  1. 15 6
      Terminal.Gui/Core.cs
  2. 10 6
      Terminal.Gui/Views/ListView.cs
  3. 3 0
      Terminal.Gui/Views/Menu.cs

+ 15 - 6
Terminal.Gui/Core.cs

@@ -350,6 +350,15 @@ namespace Terminal.Gui {
 		/// <value>The identifier.</value>
 		public ustring Id { get; set; } = "";
 
+		/// <summary>
+		/// Returns a value indicating if this View is currently on Top (Active)
+		/// </summary>
+		public bool IsCurrentTop {
+			get {
+				return Application.Current == this;
+			}
+		}
+
 		/// <summary>
 		/// Gets or sets a value indicating whether this <see cref="View"/> want mouse position reports.
 		/// </summary>
@@ -531,7 +540,7 @@ namespace Terminal.Gui {
 		/// <param name="region">The region that must be flagged for repaint.</param>
 		public void SetNeedsDisplay (Rect region)
 		{
-			if (NeedDisplay.IsEmpty)
+			if (NeedDisplay == null || NeedDisplay.IsEmpty)
 				NeedDisplay = region;
 			else {
 				var x = Math.Min (NeedDisplay.X, region.X);
@@ -1015,7 +1024,7 @@ namespace Terminal.Gui {
 
 			if (subviews != null) {
 				foreach (var view in subviews) {
-					if (!view.NeedDisplay.IsEmpty || view.childNeedsDisplay) {
+					if (view.NeedDisplay != null && (!view.NeedDisplay.IsEmpty || view.childNeedsDisplay)) {
 						if (view.Frame.IntersectsWith (clipRect) && view.Frame.IntersectsWith (region)) {
 
 							// FIXED: optimize this by computing the intersection of region and view.Bounds
@@ -1704,8 +1713,8 @@ namespace Terminal.Gui {
 		{
 			Application.CurrentView = this;
 
-			if (this == Application.Top || this == Application.Current) {
-				if (!NeedDisplay.IsEmpty) {
+			if (IsCurrentTop) {
+				if (NeedDisplay != null && !NeedDisplay.IsEmpty) {
 					Driver.SetAttribute (Colors.TopLevel.Normal);
 					Clear (region);
 					Driver.SetAttribute (Colors.Base.Normal);
@@ -1887,7 +1896,7 @@ namespace Terminal.Gui {
 		{
 			Application.CurrentView = this;
 
-			if (!NeedDisplay.IsEmpty) {
+			if (NeedDisplay != null && !NeedDisplay.IsEmpty) {
 				DrawFrameWindow ();
 			}
 			contentView.Redraw (contentView.Bounds);
@@ -2487,7 +2496,7 @@ namespace Terminal.Gui {
 					Iteration?.Invoke (null, EventArgs.Empty);
 				} else if (wait == false)
 					return;
-				if (!state.Toplevel.NeedDisplay.IsEmpty || state.Toplevel.childNeedsDisplay) {
+				if (state.Toplevel.NeedDisplay != null && (!state.Toplevel.NeedDisplay.IsEmpty || state.Toplevel.childNeedsDisplay)) {
 					state.Toplevel.Redraw (state.Toplevel.Bounds);
 					if (DebugDrawBounds)
 						DrawBounds (state.Toplevel);

+ 10 - 6
Terminal.Gui/Views/ListView.cs

@@ -593,12 +593,16 @@ namespace Terminal.Gui {
 		{
 			container.Move (col, line);
 			var t = src [item];
-			if (t is ustring) {
-				RenderUstr (driver, (ustring)t, col, line, width);
-			} else if (t is string) {
-				RenderUstr (driver, (string)t, col, line, width);
-			} else
-				RenderUstr (driver, t.ToString (), col, line, width);
+			if (t == null) {
+				RenderUstr (driver, ustring.Make(""), col, line, width);
+			} else {
+				if (t is ustring) {
+					RenderUstr (driver, (ustring)t, col, line, width);
+				} else if (t is string) {
+					RenderUstr (driver, (string)t, col, line, width);
+				} else
+					RenderUstr (driver, t.ToString (), col, line, width);
+			}
 		}
 
 		/// <summary>

+ 3 - 0
Terminal.Gui/Views/Menu.cs

@@ -162,6 +162,9 @@ namespace Terminal.Gui {
 		/// <param name="children">The items in the current menu.</param>
 		public MenuBarItem (ustring title, MenuItem [] children)
 		{
+			if (children == null)
+				throw new ArgumentNullException (nameof (children), "The parameter cannot be null. Use an empty array instead.");
+
 			SetTitle (title ?? "");
 			Children = children;
 		}