Bind int property with StringFormat in BorderThinkness - c#

I have a template with a own property BorderWidth:
public static readonly DependencyProperty BorderWidthProperty = DependencyProperty.Register("BorderWidth", typeof(int), typeof(ProjectOverviewSensor), new PropertyMetadata(1));
Now i want to bind this property to BorderThickness with StringFormat in my template for create a border to specific sides. But it is ever 1 in all four sides.
<Border BorderThickness="{Binding Path=BorderWidth, RelativeSource={RelativeSource TemplatedParent}, StringFormat='{}{0},0,{0},0'}"></Border>
How i can bind the property only to the sides of border control, that i want? Are there a alternative to stringformat?

Binding.StringFormat only works on properties of type System.String.
It is a different story with a string written in XAML, since here, the XAML parser converts the string to a thickness value during parsing.
To do what you want you will need a converter on the binding:
class MyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == DependencyProperty.UnsetValue)
return value;
return new Thickness((int)value,0, (int)value, 0);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((Thickness)value).Left;
}
}
And use like this:
<Window.Resources>
<MyConverter x:Key="ToThickness"/>
</Window.Resources>
<Border BorderThickness="{Binding Path=BorderWidth, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ToThickness}"></Border>

Now i created a extended converter and I want him not to hide from you.
public class CustomThicknessConverter : IValueConverter
{
protected readonly char SplitChar = ',';
protected readonly char ReplaceAt = '#';
/// <summary>
/// Create a thickness with custom format(for example #,2,#,5).
/// </summary>
/// Number for default width.
/// # for given border width.
/// ; for split the chars.
/// For example '#,0,#,0' with 1 as value return a new thickness
/// with Left = 1, Top = 0, Right = 1, Bottom = 0.
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value == DependencyProperty.UnsetValue)
return value;
var borderWidth = value as double?;
var format = parameter.ToString().Split(SplitChar);
if(format.Length == 1)
return new Thickness(GetValue(borderWidth, format[0]));
else if(format.Length == 2)
{
return new Thickness()
{
Left = GetValue(borderWidth, format[0]),
Top = GetValue(borderWidth, format[1]),
Right = GetValue(borderWidth, format[0]),
Bottom = GetValue(borderWidth, format[1])
};
}
else if(format.Length == 4)
{
return new Thickness()
{
Left = GetValue(borderWidth, format[0]),
Top = GetValue(borderWidth, format[1]),
Right = GetValue(borderWidth, format[2]),
Bottom = GetValue(borderWidth, format[3])
};
}
return new Thickness(0);
}
private double GetValue(double? value, string format)
{
if(format.FirstOrDefault() == ReplaceAt) return value ?? 0;
double result;
return (Double.TryParse(format, out result)) ? result : 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
And in xaml:
<local:CustomThicknessConverter x:Key="CustomThicknessConverter" />
<Border BorderThickness="{Binding BorderWidth, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource CustomThicknessConverter}, ConverterParameter='0,#,0,#'}">
</Border>

Related

Using FindResource in an IValueConverter

I have this value converter which converts a number to a brush color. What I need to do is to change the line return Brushes.Red; into return (Brush)FindResource("PrimaryHueMidBrush");, so I can return the color of the main theme. The problem is that I don't know how to declare (Brush)FindResource("PrimaryHueMidBrush");. Any help is welcome. Thank you in advance.
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double.TryParse(value.ToString(), out double val);
if (val == 1)
{
return Brushes.Red;
}
else if(val == 0.5)
{
return Brushes.MediumVioletRed;
}
else if(val==0)
{
return Brushes.Transparent;
}
else
{
return Brushes.Transparent;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
Instead of calling FindResource in the converter, you'd better add one or more properties for the dynamic Brushes:
public class YourConverter : IValueConverter
{
public Brush FirstBrush { get; set; }
public Brush SecondBrush { get; set; }
public object Convert(
object value, Type targetType, object parameter, CultureInfo culture)
{
double val = (double)value;
if (val >= 1)
{
return FirstBrush;
}
if (val >= 0.5)
{
return SecondBrush;
}
return Brushes.Transparent;
}
public object ConvertBack(
object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
You would declare it in the Resources of your Application or Window like this:
<local:YourConverter x:Key="YourConverter"
FirstBrush="{StaticResource PrimaryHueMidBrush}"
SecondBrush="MediumVioletRed"/>
To access FindResource you need a FrameworkElement so the best way to do this would probably be to use a MultiValueConverter instead and pass the element that uses the converter as a second value.
Converter:
public class WhateverThisIsCalledConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
// Insert type- and sanity-checks here
double val = (double)values[0];
FrameworkElement callingElement = (FrameworkElement)values[1];
if (val >= 1)
{
return callingElement.FindResource("PrimaryHueMidBrush");
}
if (val >= 0.5)
{
return Brushes.MediumVioletRed;
}
return Brushes.Transparent;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
return Enumerable.Repeat(DependencyProperty.UnsetValue, targetTypes.Length).ToArray();
}
}
Usage in XAML:
<Window.Resources>
<local:WhateverThisIsCalledConverter x:Key="Converter"/>
<SolidColorBrush Color="Red" x:Key="PrimaryHueMidBrush"/>
</Window.Resources>
<Grid>
<Grid.Background>
<MultiBinding Converter="{StaticResource Converter}">
<Binding Path="Value"/>
<Binding RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Grid.Background>
</Grid>
Couple of notes on your current implementation:
Try avoiding == on doubles, they are not infinitely precice.
You don't need all those elses when you return in the if before.
The ConvertBack method should be implemented (Free choice of other Exceptions, Binding.DoNothing and DependencyProperty.UnsetValue).
If you know your value is a double, simply cast it instead.

Check if Hex string is correct in Converter

I made a text box to input and show color Hex value.The binding is twoway to a color property of a parent.
Everything is working but, I need to make sure, in case I enter manually a Hex in the text box, and if this a not correct string, then use and display the current Hex value of the color, rather than trying to change it.
Here is what I tried but obviously it's not working, I'm a beginner and I have only a little experience with converter and WPF. If I write anything but not a valid Hex string, at the moment the textbox gets a red outline, but I wish that in this case, the Hex previous string reappears.
[ValueConversion(typeof(Color), typeof(String))]
public class ColorToStringConverter : IValueConverter
{
public Object Convert(Object value, Type targetType, Object parameter, CultureInfo culture)
{
Color colorValue = (Color)value;
return ColorNames.GetColorName(colorValue);
}
public Object ConvertBack(Object value, Type targetType, Object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class ColorHexConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var hexCode = System.Convert.ToString(value);
//if (string.IsNullOrEmpty(hexCode))
// return null;
try
{
var color = (Color)ColorConverter.ConvertFromString(hexCode);
return color;
}
catch
{
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var hexCode = System.Convert.ToString(value);
Regex myRegex = new Regex("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$");
bool isValid = false;
if (string.IsNullOrEmpty(hexCode))
{
isValid = false;
}
else
{
isValid = myRegex.IsMatch(hexCode);
}
try
{
return hexCode;
}
catch
{
return null;
}
}
}
And the C# class for the TextBox
public class ColorHex : TextBox
{
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Key == Key.Enter)
{
BindingExpression bindingExpression = BindingOperations.GetBindingExpression(this, TextProperty);
if (bindingExpression != null)
bindingExpression.UpdateSource();
}
}
}
And its xaml in Generic.xaml
<local:ColorHex x:Name="PART_ColorHex" Style="{StaticResource ColorPickerTextBox}" Text="{Binding SelectedColor, Converter={StaticResource ColorToHexConverter}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ColorPicker}}}" />
Any idea ?
thank you
A valid hex color has the form '#nnn' or '#nnnnnn'.
So, the regex for this case would be: (^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)
NOw, you could add these lines of code:
var regex = #"(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)"
var match = Regex.Match(inputYouWantToCheck, regex,RegexOptions.IgnoreCase);
if (!match.Success)
{
// Color is not valid
}
Hope this helps.
What if you did something where you add a label next to the textbox to show an example of what color has been entered. You would just need to change the label color change each time.
I'd do it differently, using property to validate the color:
public Color Color { get; set; } = Colors.Red;
public string ColorText
{
get { return (new ColorConverter()).ConvertToString(Color); }
set
{
Color = (Color)ColorConverter.ConvertFromString(value);
OnPropertyChanged();
}
}
Bind to ColorText, it will throw in case it's wrong hex, and you can use ExceptionValidationRule to display it (as a red border):
<TextBox Text="{local:ExceptionBinding Path=ColorText}" />
where
public class ExceptionBinding : Binding
{
public ExceptionBinding() : base()
{
ValidationRules.Add(new ExceptionValidationRule());
}
}
As a bonus you can enter known colors as text, e.g. "Red":

Converter to show description of an enum, and convert back to enum value on selecting an item from combo box in wpf

I am using an enum to enlist values in my combobox.
I want to write a converter that would show the "description" of the selected enum value. And, when selected, it would return the enum value.
Most of the converters online have not implemented the ConvertBack() method (which is why I am posting here).
Here is ConvertBack method:
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
Full Converter Code:
public class EnumConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null) return DependencyProperty.UnsetValue;
return GetDescription((Enum)value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
public static string GetDescription(Enum en)
{
Type type = en.GetType();
MemberInfo[] memInfo = type.GetMember(en.ToString());
if (memInfo != null && memInfo.Length > 0)
{
object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attrs != null && attrs.Length > 0)
{
return ((DescriptionAttribute)attrs[0]).Description;
}
}
return en.ToString();
}
}
EDIT
Here is my ComboBox XAML:
<ComboBox ItemsSource="{Binding SampleValues}"
SelectedItem="{Binding SelectedValue, Converter={StaticResource enumConverter}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={StaticResource enumConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I know this is an old question, but for some reason, this is rather complicated, even though it seems like it'd be a pretty common task (I'm currently doing this on a UWP app). Using a combination of the accepted answer, some other items I found, and a bit of my own work, here's the simplest way I've found to accomplish this menial task. In short:
Define your enum along w/ setting the description in the Display attribute
Create a converter that converts from an enum value to the description
In your viewmodel, expose a collection of enum values from which to choose, the selected enum value, then initialize those
Define a couple of handy enum extension methods
Finally, some simple binding to the ComboBox, just overriding its ItemTemplate to use the converter.
Enum
public enum EnumOptions
{
[Display(Description = "Option 1")]
OptionOne= 1,
[Display(Description = "Option 2")]
OptionTwo,
[Display(Description = "Option 3")]
OptionThree
}
Converter
public class EnumToDisplayConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var enumValue = value as Enum;
return enumValue == null ? DependencyProperty.UnsetValue : enumValue.GetDescriptionFromEnumValue();
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return value;
}
}
Viewmodel (partial)
public IReadOnlyList<EnumOptions> Options { get; }
private EnumOptions _selectedOption;
public EnumOptions SelectedOption
{
get { return _selectedOption; }
set
{
_selectedOption = value;
OnPropertyChanged(() => SelectedOption);
}
}
// Initialization in constructor
Options = EnumExtensions.GetValues<EnumOptions>().ToArray();
// If you want to set a default.
SelectedOption = Options[0];
Extensions
public static class EnumExtensions
{
public static string GetDescriptionFromEnumValue(this Enum value)
{
var attribute = value.GetType()
.GetField(value.ToString())
.GetCustomAttributes(typeof(DisplayAttribute), false)
.SingleOrDefault() as DisplayAttribute;
return attribute == null ? value.ToString() : attribute.Description;
}
/// <summary>
/// Enumerates all enum values
/// </summary>
/// <typeparam name="T">Enum type</typeparam>
/// <returns>IEnumerable containing all enum values</returns>
/// <see cref="http://stackoverflow.com/questions/972307/can-you-loop-through-all-enum-values"/>
public static IEnumerable<T> GetValues<T>()
{
return Enum.GetValues(typeof (T)).Cast<T>();
}
}
XAML (partial)
<TextBlock Grid.Row="1">Choose an option</TextBlock>
<ComboBox Grid.Row="2"
ItemsSource="{Binding Options}"
SelectedItem="{Binding SelectedOption, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource EnumToDisplayConverter}}"></TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
[ValueConversion(typeof(MyEnum), typeof(String))]
public class MyEnumConverter : IValueConverter
{
public object Convert(object value,
Type targetType,
object parameter,
CultureInfo culture)
{
var enumVal = (MyEnum)value;
// in this example, this is an extension method
return enumValue.Description();
}
public object ConvertBack(object value,
Type targetType,
object parameter,
CultureInfo culture)
{
var enumDesc = value as string;
MyEnum val;
if (Enum.TryParse(typeof(MyEnum), strValue, out val))
{
return val;
}
return DependencyProperty.UnsetValue;
}
}
The extension method in the example might look like this:
public static string Description(this MyEnum enumVal)
{
// you could use a switch statement here;
// or maybe a Dictionary
}
Supplement to the above examples to show decorating the enum with attributes.
sealed class DescriptionAttribute : Attribute
{
readonly string description;
public DescriptionAttribute(string description)
{
this.description = description;
}
public string Description
{
get { return description; }
}
}
enum Vehicle
{
[Description("Benz")]
Car,
[Description("Volvo")]
Bus,
[Description("Honda")]
Bike
}
BTW, I wonder why you needed to convert back the description to enum. If you provide the enums itself as ItemSource, you can use the description technique to show the display value in the ComboBox, however, once an item is selected you can directly have an enum as selected item.
Here is my working well example:
Enum definition:
public enum MyEnum
{
[Description("Exchange 2007")]
E2007,
[Description("Exchange 2010")]
E2010,
[Description("Exchange 2013")]
E2013,
};
Helper class:
public static class cHelperClass
{
#region GetValuesAndDescriptions
public static object[] GetValuesAndDescriptions(Type enumType)
{
var kvPairList = new List<KeyValuePair<string, string>>();
var listValue = Enum.GetValues(enumType);
for (var i = 0; i < listValue.Length; i++)
{
var value = listValue.GetValue(i);
var enumValue = (Enum)listValue.GetValue(i);
kvPairList.Add(new KeyValuePair<string, string>(value.ToString(), GetDescription(enumValue)));
}
var valuesAndDescriptions = from kv in kvPairList select new
{
Value = kv.Key,
Description = kv.Value
};
return valuesAndDescriptions.ToArray();
}
public static string GetDescription(this Enum value)
{
var fieldInfo = value.GetType().GetField(value.ToString());
var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
return (attributes.Length > 0) ? attributes[0].Description : value.ToString();
}
public static string GetStringValue(this Enum enumItem)
{
return enumItem
.GetType()
.GetField(enumItem.ToString())
.GetCustomAttributes<StringValueAttribute>()
.Select(a => a.Value)
.FirstOrDefault() ?? enumItem.ToString();
}
public static string GetName(Type enumType, object value)
{
return Enum.GetName(enumType, value);
}
#endregion
}
XAML:
<UserControl.Resources>
<!-- ObjectDataProvider für WindowStyles -->
<ObjectDataProvider x:Key="myEnumResource" MethodName="GetValuesAndDescriptions" ObjectType="classes:cHelperClass">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="classes:MyEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</UserControl.Resources>
<ComboBox ItemsSource="{Binding Source={StaticResource myEnumResource}}" DisplayMemberPath="Description" SelectedValuePath="Value" SelectedValue="{Binding MyEnum, Mode=TwoWay}" />

How to pass multiple converter parameter in generic Enum to Boolean Converter

I have been through this How to bind RadioButtons to an enum?
and accepted answer to this question contains use of generic Enum to Boolean converter.
my problem is that I am having two radio buttons in View and an enum
public Enum LinkType
{
A,
B,
C,
D,
E,
F
}
In ViewModel I have a property Called
public LinkType MyLinktype
{
get;set;
}
my first radio button can be true if property of enum in ViewModel is having value among A,C,E and second radio button can be true if property of enum in ViewModel is having value among.
B,D,F
So, How can I pass multiple values in the converter parameter in generic EnumTo Boolean Converter which is as following
public class EnumBooleanConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string parameterString = parameter as string;
if (parameterString == null)
return DependencyProperty.UnsetValue;
if (Enum.IsDefined(value.GetType(), value) == false)
return DependencyProperty.UnsetValue;
object parameterValue = Enum.Parse(value.GetType(), parameterString);
return parameterValue.Equals(value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string parameterString = parameter as string;
if (parameterString == null)
return DependencyProperty.UnsetValue;
return Enum.Parse(targetType, parameterString);
}
So what changes I have to make in converter if I want something like this in the XAML
<RadioButton IsChecked="{Binding Path=MyLinktype, Converter={StaticResource enumBooleanConverter}, ConverterParameter=A,C,F}">Odd LinkType</RadioButton>
<RadioButton IsChecked="{Binding Path=Mylinktype, Converter={StaticResource enumBooleanConverter}, ConverterParameter=B,D,E}">Even Link Type</RadioButton>
You can define an array in xaml:
<x:Array Type="LinkType" x:Key="ar">
<LinkType>A</LinkType>
<LinkType>B</LinkType>
</x:Array>
And then pass it as parameter
<RadioButton IsChecked="{Binding Path=MyLinktype, Converter={StaticResource enumBooleanConverter}, ConverterParameter={StaticResource ar}}">Odd LinkType</RadioButton>
You'll have to fix your converter tho, in order to properly handle array as converter parameter.
Firstly, I think "Flags" attribute is the key to resolve the problem:
[Flags]
public enum LinkType
{
A=1,
B=2,
C=4,
D=8,
E=16
}
And then, I implement the converter like this:
public class LinkTypeToBoolCvt : IValueConverter
{
#region | Members of IValueConverter |
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// please refer to the implementation of "CallBack" method
throw new NotImplementedException();
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null || parameter == null) return DependencyProperty.UnsetValue;
var param= parameter.ToString();
int result;
if (int.TryParse(param,out result))
{
// ex: if the parameter is 11, the result will be "A|B|D"
return result;
}
else
{
// ex: if the parameter is "A|E", the result will be 17
var enums = param.Split(new []{"|"}, StringSplitOptions.RemoveEmptyEntries);
LinkType lt = 0;
LinkType ltTemp = 0;
foreach (var item in enums)
{
if (Enum.TryParse<LinkType>(item, out ltTemp)) lt |= ltTemp;
}
if (lt == 0) return DependencyProperty.UnsetValue;
else return lt;
}
}
#endregion
}
And, in Xaml you can use it like this:
<RadioButton IsChecked="{Binding .MyLinkType,Converter={StaticResource LinkTypeToBoolCvt},ConverterParameter=11}" />
Also like this:
<RadioButton IsChecked="{Binding .MyLinkType,Converter={StaticResource LinkTypeToBoolCvt},ConverterParameter=A|B|D}" />
if you dont use "Flags" attribute, you cannot transfer the result like "A|B|D" back to your model.
Finally, I should apologize for my poor english. ^-^
You can use following enum to boolean converter
[ValueConversion(typeof(Enum), typeof(bool))]
public class EnumToBooleanConverter : IValueConverter
{
public object Convert(object value,
Type targetType,
object parameter,
CultureInfo culture)
{
if (
(value == null)
||
(!(value is Enum))
||
(parameter == null)
)
{
return false;
}
foreach (Enum paramValue in ParseObjectToEnum(value.GetType(),
parameter))
{
if (value.Equals(paramValue))
{
return true;
}
}
return false;
}
public object ConvertBack(object value,
Type targetType,
object parameter,
CultureInfo culture)
{
object result = Binding.DoNothing;
if ((bool)value)
{
Enum[] parsedValues = ParseObjectToEnum(targetType,
parameter);
if (parsedValues.Length > 0)
{
result = parsedValues[0];
}
}
return result;
}
private static Enum[] ParseObjectToEnum(Type enumType,
object value)
{
var enumValue = value as Enum;
if (enumValue != null)
{
return new[] { enumValue };
}
var str = value as string;
if (string.IsNullOrEmpty(str))
{
throw new ArgumentException("parameter");
}
string[] strArray = str.Split(new[] { ';', ',' },
StringSplitOptions.RemoveEmptyEntries);
var enumArray = new Enum[strArray.Length];
for (int i = 0;
i < strArray.Length;
i++)
{
enumArray[i] = (Enum)Enum.Parse(enumType,
strArray[i],
true);
}
return enumArray;
}
}
and in xaml you can use like
<RadioButton IsChecked="{Binding Path=MyLinktype, Converter={StaticResource enumBooleanConverter}, ConverterParameter=A;C;F}">Odd LinkType</RadioButton>
where enumBooleanConverter is the above converter

Converter cannot be applied to a property that expects the type System.Windows.Data.IValueConverter

I am having a problem in my WPF app that I do not quite understand. I am trying to bind a fill to a different color depending on the value of a certain property.
Here are the snippets involved:
public class GeoLocations
{
private static ObservableCollection<Bus> _locations = new ObservableCollection<Bus>();
public static ObservableCollection<Bus> locations
{
get { return _locations; }
set
{
_locations = value;
}
}
.
.
.
}
public class Bus : INotifyPropertyChanged
{
private double _VSAI;
public double VSAI
{
get
{
return _VSAI;
}
set
{
_VSAI = value;
OnPropertyChanged(new PropertyChangedEventArgs("VSAI"));
}
}
public class VsaiToColorConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double vsai = (double)value;
if (vsai < App.Settings.medVSAI)
return Brushes.Green;
if (vsai >= App.Settings.medVSAI && vsai <= App.Settings.maxVSAI)
return Brushes.Yellow;
if (vsai > App.Settings.maxVSAI)
return Brushes.Red;
return Brushes.Transparent;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Then in my xaml I have the following:
in my resources I have
<local:GeoLocations x:Key="geolocs"/>
and then I have a map
<ig:GeographicProportionalSymbolSeries x:Name="ProportionalSeries"
LongitudeMemberPath="Longitude"
LatitudeMemberPath="Latitude"
ItemsSource="{Binding Source={StaticResource geolocs}, Path=locations}"
>
<!-- custom marker template for GeographicProportionalSymbolSeries -->
<ig:GeographicProportionalSymbolSeries.MarkerTemplate>
<DataTemplate>
<Ellipse x:Name="RootElement" Width="10" Height="10"
Stroke="DarkGray"
Opacity=".8"
StrokeThickness="0.5"
Fill="{Binding Path=Item.VSAI, Converter={StaticResource VSAIConverter}}">
</Ellipse>
</DataTemplate>
</ig:GeographicProportionalSymbolSeries.MarkerTemplate>
But the error I'm getting is on the FILL=..... above. I'm hoping this is an easy fix. I'm just a little too new still to understand how to fix this and what this error means.
Your converter needs to implement the IValueConverter interface. You've implemented the two methods but you omitted the IValueConverter interface so as far as the CLR is concerned, you just have a class that happens to have the same methods as IValueConverter but isn't actually implementing it.
public class VsaiToColorConverter : IValueConverter
You generally want to handle null value cases as well
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if(value == null) return Brushes.Transparent; //or null
double vsai = (double)value;
//..
}

Categories

Resources