From 13aadb69ca6e8bb8dfb609125e1aaa550d3ae9d6 Mon Sep 17 00:00:00 2001
From: Huo Yaoyuan <huoyaoyuan@hotmail.com>
Date: Wed, 20 Jan 2021 17:41:35 +0800
Subject: [PATCH 1/5] Use Enum.Parse when comparing enum with string.

---
 Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs b/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
index b565aede7a4..72dccbd3fe3 100644
--- a/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
+++ b/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
@@ -94,6 +94,11 @@ private static object ConvertToEnum(Type enumType, object value)
         {
             try
             {
+                if (value is string str)
+                {
+                    return Enum.Parse(enumType, str);
+                }
+
                 return Enum.IsDefined(enumType, value) ? Enum.ToObject(enumType, value) : null;
             }
             catch

From e225318150b96e9fffc720bed8d554d7ddb935c9 Mon Sep 17 00:00:00 2001
From: Huo Yaoyuan <huoyaoyuan@hotmail.com>
Date: Thu, 21 Jan 2021 17:26:45 +0800
Subject: [PATCH 2/5] Refine enum conversion handling.

---
 .../Triggers/IsEqualStateTrigger.cs           | 24 ++++++++-----------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs b/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
index 72dccbd3fe3..788b7da5a85 100644
--- a/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
+++ b/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
@@ -61,12 +61,13 @@ public object To
 
         internal static bool AreValuesEqual(object value1, object value2, bool convertType)
         {
-            if (value1 == value2)
+            if (object.Equals(value1, value2))
             {
                 return true;
             }
 
-            if (value1 != null && value2 != null && convertType)
+            // If they are the same type but fail with Equals check, don't bother with conversion.
+            if (value1 != null && value2 != null && value1.GetType() != value2.GetType() && convertType)
             {
                 // Try the conversion in both ways:
                 return ConvertTypeEquals(value1, value2) || ConvertTypeEquals(value2, value1);
@@ -92,19 +93,14 @@ private static bool ConvertTypeEquals(object value1, object value2)
 
         private static object ConvertToEnum(Type enumType, object value)
         {
-            try
+            // value cannot be the same type of enum now
+            return value switch
             {
-                if (value is string str)
-                {
-                    return Enum.Parse(enumType, str);
-                }
-
-                return Enum.IsDefined(enumType, value) ? Enum.ToObject(enumType, value) : null;
-            }
-            catch
-            {
-                return null;
-            }
+                string str when Enum.TryParse(enumType, str, out var e) => e, // string is most common for enum comparison
+                _ when Type.GetTypeCode(enumType) == Convert.GetTypeCode(value) // Enum.IsDefeind only allows the same type code
+                    && Enum.IsDefined(enumType, value) => Enum.ToObject(enumType, value),
+                _ => null
+            };
         }
     }
 }

From 1a63e8b8a64de4550a685bdba4c078367071dfec Mon Sep 17 00:00:00 2001
From: Huo Yaoyuan <huoyaoyuan@hotmail.com>
Date: Fri, 22 Jan 2021 02:50:57 +0800
Subject: [PATCH 3/5] Remove the check of Enum.IsDefined.

---
 Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs b/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
index 788b7da5a85..8d229d6b35a 100644
--- a/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
+++ b/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
@@ -97,8 +97,8 @@ private static object ConvertToEnum(Type enumType, object value)
             return value switch
             {
                 string str when Enum.TryParse(enumType, str, out var e) => e, // string is most common for enum comparison
-                _ when Type.GetTypeCode(enumType) == Convert.GetTypeCode(value) // Enum.IsDefeind only allows the same type code
-                    && Enum.IsDefined(enumType, value) => Enum.ToObject(enumType, value),
+                _ when Type.GetTypeCode(enumType) == Convert.GetTypeCode(value) // previous implementation uses Enum.IsDefeind which only allows the same type code
+                    => Enum.ToObject(enumType, value),
                 _ => null
             };
         }

From edc5b7b7c6d9ab8bcc91bf116e82605337c9af99 Mon Sep 17 00:00:00 2001
From: Huo Yaoyuan <huoyaoyuan@hotmail.com>
Date: Sat, 6 Feb 2021 02:04:13 +0800
Subject: [PATCH 4/5] Use explicit type checking for Enum.ToObject.

---
 .../Triggers/IsEqualStateTrigger.cs           | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs b/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
index 8d229d6b35a..6514ceb7a0e 100644
--- a/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
+++ b/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
@@ -94,13 +94,20 @@ private static bool ConvertTypeEquals(object value1, object value2)
         private static object ConvertToEnum(Type enumType, object value)
         {
             // value cannot be the same type of enum now
-            return value switch
+            if (value is string str)
             {
-                string str when Enum.TryParse(enumType, str, out var e) => e, // string is most common for enum comparison
-                _ when Type.GetTypeCode(enumType) == Convert.GetTypeCode(value) // previous implementation uses Enum.IsDefeind which only allows the same type code
-                    => Enum.ToObject(enumType, value),
-                _ => null
-            };
+                return Enum.TryParse(enumType, str, out var e) ? e : null;
+            }
+
+            if (value is int || value is uint
+                || value is byte || value is sbyte
+                || value is long || value is ulong
+                || value is short || value is ushort)
+            {
+                return Enum.ToObject(enumType, value);
+            }
+
+            return null;
         }
     }
 }

From a85e6999e0365837372c9e4f3fecf340ef9e5f2e Mon Sep 17 00:00:00 2001
From: Huo Yaoyuan <huoyaoyuan@hotmail.com>
Date: Sat, 6 Feb 2021 03:30:14 +0800
Subject: [PATCH 5/5] Upgrade to C# 9.0 and use logical pattern matching.

---
 .../Microsoft.Toolkit.Uwp.UI.csproj           |  2 +-
 .../Triggers/IsEqualStateTrigger.cs           | 22 +++++++------------
 2 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj b/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj
index e7358bf1939..d2db457a3d5 100644
--- a/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj
+++ b/Microsoft.Toolkit.Uwp.UI/Microsoft.Toolkit.Uwp.UI.csproj
@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <TargetFrameworks>uap10.0.17763</TargetFrameworks>
-    <LangVersion>8.0</LangVersion>
+    <LangVersion>9.0</LangVersion>
     <Title>Windows Community Toolkit UI</Title>
     <Description>
       This library provides UI components, such as XAML extensions, helpers, converters and more. It is part of the Windows Community Toolkit.
diff --git a/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs b/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
index 6514ceb7a0e..414d2e12626 100644
--- a/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
+++ b/Microsoft.Toolkit.Uwp.UI/Triggers/IsEqualStateTrigger.cs
@@ -67,7 +67,8 @@ internal static bool AreValuesEqual(object value1, object value2, bool convertTy
             }
 
             // If they are the same type but fail with Equals check, don't bother with conversion.
-            if (value1 != null && value2 != null && value1.GetType() != value2.GetType() && convertType)
+            if (value1 is not null && value2 is not null && convertType
+                && value1.GetType() != value2.GetType())
             {
                 // Try the conversion in both ways:
                 return ConvertTypeEquals(value1, value2) || ConvertTypeEquals(value2, value1);
@@ -94,20 +95,13 @@ private static bool ConvertTypeEquals(object value1, object value2)
         private static object ConvertToEnum(Type enumType, object value)
         {
             // value cannot be the same type of enum now
-            if (value is string str)
+            return value switch
             {
-                return Enum.TryParse(enumType, str, out var e) ? e : null;
-            }
-
-            if (value is int || value is uint
-                || value is byte || value is sbyte
-                || value is long || value is ulong
-                || value is short || value is ushort)
-            {
-                return Enum.ToObject(enumType, value);
-            }
-
-            return null;
+                string str => Enum.TryParse(enumType, str, out var e) ? e : null,
+                int or uint or byte or sbyte or long or ulong or short or ushort
+                    => Enum.ToObject(enumType, value),
+                _ => null
+            };
         }
     }
 }