Last active
February 21, 2019 07:38
-
-
Save haavamoa/35d0064f72f3d4edc2d705433f2eed0c to your computer and use it in GitHub Desktop.
Awesome converter to use when you have a list of bools that you want to convert
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Globalization; | |
using System.Linq; | |
using System.Windows; | |
using System.Windows.Data; | |
using System.Windows.Markup; | |
namespace MynameSpace | |
{ | |
/// <summary> | |
/// A converter to run a logical gate on multiple boolean values <see cref="LogicalGate"/>. | |
/// Return value can be set by using <see cref="ReturnType"/> | |
/// </summary> | |
public class LogicalExpressionConverter : MarkupExtension, IMultiValueConverter | |
{ | |
public LogicalGate LogicalGate { get; set; } | |
public ReturnType ReturnType { get; set; } | |
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) | |
{ | |
if (values == null) | |
{ | |
switch (ReturnType) | |
{ | |
case ReturnType.Visibility: | |
return Visibility.Collapsed; | |
case ReturnType.Boolean: | |
return false; | |
case ReturnType.Undefined: | |
return Visibility.Collapsed; | |
} | |
} | |
foreach (var value in values) | |
{ | |
if(value == DependencyProperty.UnsetValue || value == null) | |
{ | |
switch (ReturnType) | |
{ | |
case ReturnType.Visibility: | |
return Visibility.Collapsed; | |
case ReturnType.Boolean: | |
return false; | |
case ReturnType.Undefined: | |
return Visibility.Collapsed; | |
} | |
} | |
} | |
try | |
{ | |
List<bool> bools = values.Cast<bool>().ToList(); | |
bool logcalExpression = false; | |
switch (LogicalGate) | |
{ | |
case LogicalGate.Undefined: | |
throw new ArgumentException($"LogicalConverter undefined property: {nameof(LogicalGate)}"); | |
case LogicalGate.And: | |
logcalExpression = bools.All(b => b); | |
break; | |
case LogicalGate.Nand: | |
logcalExpression = bools.All(b => !b); | |
break; | |
case LogicalGate.Or: | |
logcalExpression = bools.Any(b => b); | |
break; | |
case LogicalGate.Nor: | |
logcalExpression = bools.Any(b => !b); | |
break; | |
default: | |
throw new ArgumentOutOfRangeException(); | |
} | |
switch (ReturnType) | |
{ | |
case ReturnType.Boolean: | |
return logcalExpression; | |
case ReturnType.Visibility: | |
return logcalExpression ? Visibility.Visible : Visibility.Collapsed; | |
case ReturnType.Undefined: | |
break; | |
default: | |
throw new ArgumentOutOfRangeException(); | |
} | |
} | |
catch (Exception e) | |
{ | |
throw new Exception("LogicalExpressionConverter : Something went wrong while converting:", e); | |
} | |
return null; | |
} | |
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) | |
{ | |
throw new NotImplementedException("EmbeddedBrowser : LogicalExpressionConverter does not support convert back"); | |
} | |
public override object ProvideValue(IServiceProvider serviceProvider) | |
{ | |
return this; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.Windows; | |
namespace MyNameSpace | |
{ | |
[TestClass] | |
public class LogicalExpressionConverterTests | |
{ | |
private LogicalExpressionConverter m_cut; | |
[TestInitialize] | |
public void BeforeEachTest() | |
{ | |
m_cut = new LogicalExpressionConverter(); | |
} | |
[TestMethod] | |
public void Convert_ValuesAreNull_NegativeResult() | |
{ | |
var convertedBoolValue = (bool)Convert(null, returnType: ReturnType.Boolean); | |
var convertedVisibilityValue = (Visibility)Convert(null, returnType: ReturnType.Visibility); | |
Assert.IsFalse(convertedBoolValue); | |
Assert.AreEqual(convertedVisibilityValue, Visibility.Collapsed); | |
} | |
[TestMethod] | |
public void Convert_OneValueIsNull_NegativeResult() | |
{ | |
var values = new object[] {true, true, null}; | |
var convertedBoolValue = (bool)Convert(values, returnType:ReturnType.Boolean); | |
var convertedVisibilityValue = (Visibility)Convert(values, returnType: ReturnType.Visibility); | |
Assert.IsFalse(convertedBoolValue); | |
Assert.AreEqual(convertedVisibilityValue, Visibility.Collapsed); | |
} | |
[TestMethod] | |
public void Convert_OneValueDependencyPropertyUnsetValue_NegativeResult() | |
{ | |
var values = new[] { true, true, DependencyProperty.UnsetValue }; | |
var convertedBoolValue = (bool)Convert(values, returnType:ReturnType.Boolean); | |
var convertedVisibilityValue = (Visibility)Convert(values, returnType: ReturnType.Visibility); | |
Assert.IsFalse(convertedBoolValue); | |
Assert.AreEqual(convertedVisibilityValue, Visibility.Collapsed); | |
} | |
[TestMethod] | |
public void Convert_UndefinedLogicalGate_ThrowsException() | |
{ | |
var values = new object[] { true, true, true}; | |
try | |
{ | |
Convert(values); | |
Assert.Fail(); | |
} | |
catch (Exception e) | |
{ | |
if (!(e.InnerException is ArgumentException)) | |
{ | |
Assert.Fail(); | |
} | |
} | |
} | |
[TestMethod] | |
public void Convert_AndLogicalGate_AllValuesTrue_PositiveResult() | |
{ | |
var values = new object[] { true, true, true }; | |
var convertedBoolValue = (bool)Convert(values, logicalGate:LogicalGate.And, returnType: ReturnType.Boolean); | |
var convertedVisibilityValue = (Visibility)Convert(values, logicalGate: LogicalGate.And, returnType: ReturnType.Visibility); | |
Assert.IsTrue(convertedBoolValue); | |
Assert.AreEqual(convertedVisibilityValue, Visibility.Visible); | |
} | |
[TestMethod] | |
public void Convert_AndLogicalGate_OneValueFalse_ReturnTypeBoolean_IsFalse() | |
{ | |
var values = new object[] { true, true, false }; | |
var convertedBoolValue = (bool)Convert(values, logicalGate:LogicalGate.And, returnType:ReturnType.Boolean); | |
var convertedVisibilityValue = (Visibility)Convert(values, logicalGate: LogicalGate.And, returnType: ReturnType.Visibility); | |
Assert.IsFalse(convertedBoolValue); | |
Assert.AreEqual(convertedVisibilityValue, Visibility.Collapsed); | |
} | |
[TestMethod] | |
public void Convert_NandLogicalGate_NoValuesAreTrue_PositiveResult() | |
{ | |
var values = new object[] { false, false, false }; | |
var convertedBoolValue = (bool)Convert(values, logicalGate: LogicalGate.Nand, returnType: ReturnType.Boolean); | |
var convertedVisibilityValue = (Visibility)Convert(values, logicalGate: LogicalGate.Nand, returnType: ReturnType.Visibility); | |
Assert.IsTrue(convertedBoolValue); | |
Assert.AreEqual(convertedVisibilityValue, Visibility.Visible); | |
} | |
[TestMethod] | |
public void Convert_NandLogicalGate_OneValueIsTrue_NegativeResult() | |
{ | |
var values = new object[] { false, true, false }; | |
var convertedBoolValue = (bool)Convert(values, logicalGate: LogicalGate.Nand, returnType: ReturnType.Boolean); | |
var convertedVisibilityValue = (Visibility)Convert(values, logicalGate: LogicalGate.Nand, returnType: ReturnType.Visibility); | |
Assert.IsFalse(convertedBoolValue); | |
Assert.AreEqual(convertedVisibilityValue, Visibility.Collapsed); | |
} | |
[TestMethod] | |
public void Convert_OrLogicalGate_OneValueIsTrue_PositiveResult() | |
{ | |
var values = new object[] { false, true, false }; | |
var convertedBoolValue = (bool)Convert(values, logicalGate: LogicalGate.Or, returnType: ReturnType.Boolean); | |
var convertedVisibilityValue = (Visibility)Convert(values, logicalGate: LogicalGate.Or, returnType: ReturnType.Visibility); | |
Assert.IsTrue(convertedBoolValue); | |
Assert.AreEqual(convertedVisibilityValue, Visibility.Visible); | |
} | |
[TestMethod] | |
public void Convert_OrLogicalGate_AllValuesAreFalse_NegativeResult() | |
{ | |
var values = new object[] { false, false, false }; | |
var convertedBoolValue = (bool)Convert(values, logicalGate: LogicalGate.Or, returnType: ReturnType.Boolean); | |
var convertedVisibilityValue = (Visibility)Convert(values, logicalGate: LogicalGate.Or, returnType: ReturnType.Visibility); | |
Assert.IsFalse(convertedBoolValue); | |
Assert.AreEqual(convertedVisibilityValue, Visibility.Collapsed); | |
} | |
[TestMethod] | |
public void Convert_NorLogicalGate_OneValueIsFalse_PositiveResult() | |
{ | |
var values = new object[] { true, false, true }; | |
var convertedBoolValue = (bool)Convert(values, logicalGate: LogicalGate.Nor, returnType: ReturnType.Boolean); | |
var convertedVisibilityValue = (Visibility)Convert(values, logicalGate: LogicalGate.Nor, returnType: ReturnType.Visibility); | |
Assert.IsTrue(convertedBoolValue); | |
Assert.AreEqual(convertedVisibilityValue, Visibility.Visible); | |
} | |
[TestMethod] | |
public void Convert_NorLogicalGate_AllValuesAreTrue_NegativeResult() | |
{ | |
var values = new object[] { true, true, true }; | |
var convertedBoolValue = (bool)Convert(values, logicalGate: LogicalGate.Nor, returnType: ReturnType.Boolean); | |
var convertedVisibilityValue = (Visibility)Convert(values, logicalGate: LogicalGate.Nor, returnType: ReturnType.Visibility); | |
Assert.IsFalse(convertedBoolValue); | |
Assert.AreEqual(convertedVisibilityValue, Visibility.Collapsed); | |
} | |
private object Convert(object[] values, LogicalGate logicalGate = LogicalGate.Undefined, ReturnType returnType=ReturnType.Undefined) | |
{ | |
m_cut.LogicalGate = logicalGate; | |
m_cut.ReturnType = returnType; | |
return m_cut.Convert(values, null, null, null); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace MynameSpace | |
{ | |
public enum LogicalGate | |
{ | |
Undefined, //Default, non-existing logical expression | |
And, | |
Nand, | |
Or, | |
Nor | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Separator IsTabStop="False"> | |
<!-- Shows the separator if first, second or thrid element is visible --> | |
<Separator.Visibility> | |
<MultiBinding Converter="{Converters:LogicalExpressionConverter LogicalGate=Or, ReturnType=Visibility}"> | |
<Binding ElementName="MyFirstElement" | |
Path="IsVisible" /> | |
<Binding ElementName="MySecondElement" | |
Path="IsVisible" /> | |
<Binding ElementName="MyThirdElement" | |
Path="IsVisible" /> | |
</MultiBinding> | |
</Separator.Visibility> | |
</Separator> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace MyNameSpace | |
{ | |
public enum ReturnType | |
{ | |
Undefined, //Default, non-existing return type | |
Visibility, | |
Boolean, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment