Getting specific object out of public class in silverlight - c#

Hey guys i have this converter class :
public class InboxItemValueConverters : IValueConverter
{
public object Convert(object value, System.Type targetType,
object parameter, CultureInfo culture)
{
int urgency = (int)value;
Brush brush = new SolidColorBrush();
if (urgency == 0)
{
brush = new SolidColorBrush(Colors.Green); }
else if (urgency == 1)
{
brush = new SolidColorBrush(Colors.Yellow);
}
else if (urgency == 2)
{
brush = new SolidColorBrush(Colors.Red);
}
return brush;
}
public object ConvertBack(object value, System.Type targetType,
object parameter, CultureInfo culture)
{
return null;
}
public object ConvDateToShort(object value, System.Type targetType,
object parameter, CultureInfo culture)
{
DateTime DT = (DateTime)value;
return DT.ToShortDateString();
}
public object Convdateback(object value, System.Type targetType,
object parameter, CultureInfo culture)
{
return null;
}
}
and this is how i referenced it and used it the first time :
<src:InboxItemValueConverters x:Key="converttocolor" />
<Canvas Background="{Binding Urgency, Converter={StaticResource converttocolor}}"
no in the class,as you guys can see i have a date converter in there? how would i go around getting to that object through the xaml? want to convert date in another control, from same class
new xaml :
Text="{Binding DocDate , Converter={StaticResource converttocolor}}"
thanks in advance!
i am using visual studio 2012/windows phone 8/c#/silverlight

You have to move your date converter out of the colorconverter class into it's own class
public class DateValueConverter : IValueConverter
{
public object Convert(object value, System.Type targetType,
object parameter, CultureInfo culture)
{
DateTime DT = (DateTime)value;
return DT.ToShortDateString();
}
public object ConvertBack(object value, System.Type targetType,
object parameter, CultureInfo culture)
{
return null;
}
}
Then declare it at the top like you did your color converter and then change the converter to point to the date converter's key
//This needs to be declared below the colorconverter resource
<src:DateValueConverter x:Key="dateConverter" />
Text="{Binding DocDate , Converter={StaticResource dateConverter}}"

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.

The Type local:TextInputToVisibilityConverter Could Not Be Found

I was looking around for how to do a placeholder in WPF, and I found the answer here. I used the XAML Code in my file, and it gave me the following error: The Type local:TextInputToVisibilityConverter Could Not Be Found. The line looks like this:
<local:TextInputToVisibilityConverter x:Key="TextInputToVisibilityConverter" />
I'm confused why it's giving me this error because I have the TextInputToVisibilityConverter in my c# code:
public class TextInputToVisibilityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// Always test MultiValueConverter inputs for non-null
// (to avoid crash bugs for views in the designer)
if (values[0] is bool && values[1] is bool)
{
bool hasText = !(bool)values[0];
bool hasFocus = (bool)values[1];
if (hasFocus || hasText)
return Visibility.Collapsed;
}
return Visibility.Visible;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Help would be greatly appreciated.
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// Always test MultiValueConverter inputs for non-null
// (to avoid crash bugs for views in the designer)
if (values[0] is bool && values[1] is bool)
{
bool hasText = !(bool)values[0];
bool hasFocus = (bool)values[1];
if (hasFocus || hasText)
return Visibility.Collapsed;
}
return Visibility.Visible;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
string[] values = null;
if (value != null)
{
values = value.ToString().Split(' ');
return values;
}
else
{
return null;
}
}
You should have changed the same name converter x:key:name and should have filled the Convert back.

FormatString on WPF-DataGrid has no effect

i have a small problem with FormatString in my WPF-DataGrid. I use DataGridTextColumn for the column. My DataSource is a IList<IDictionary<string, string>>
My problem is, that if i set StringFormat, it doesn't have any effect on the column.
This is my binding code:
cColumn.Binding = new Binding("[" + Config.InternName.ToLower() + "]");
And this is how i set my FormatString:
#region [Date-Time Formating]
if (Config.DateTimeFormat.Trim() != "")
{
string cDateTimeFormat = Config.DateTimeFormat.Trim();
(cColumn.Binding as Binding).StringFormat = cDateTimeFormat;
}
#endregion
I have tried a lot DateTime-StringFomrats, but nothing solve my problem.
Thank you!
Here is my solution:
I can't simple use FormatString, without binding a datetime. So i wrote an IValueconverter:
public class StringDateTimeValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
DateTime cOutDateTime = DateTime.Now;
if (DateTime.TryParse(value.ToString(), out cOutDateTime))
{
return cOutDateTime;
}
else
{
return DependencyProperty.UnsetValue;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value.ToString();
}
}

How do I implement a CollectionLengthToVisibility converter?

I want to implement a converter so that certain XAML elements only appear/disappear if there are items in an ObservableCollection.
I have referenced How to access generic property without knowing the closed generic type but cannot get it to work with my implementation. It build and deploys OK (to Windows Phone 7 emulator and device) but does not work. Moreover Blend throws an exception and will no longer render the page,
NullReferenceException: Object reference not set to an instance of an
object.
Here is what I have so far,
// Sets the vsibility depending on whether the collection is empty or not depending if parameter is "VisibleOnEmpty" or "CollapsedOnEmpty"
public class CollectionLengthToVisibility : System.Windows.Data.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo cultureInfo)
{
// From https://stackoverflow.com/questions/4592644/how-to-access-generic-property-without-knowing-the-closed-generic-type
var p = value.GetType().GetProperty("Length");
int? length = p.GetValue(value, new object[] { }) as int?;
string s = (string)parameter;
if ( ((length == 0) && (s == "VisibleOnEmpty"))
|| ((length != 0) && (s == "CollapsedOnEmpty")) )
{
return Visibility.Visible;
}
else
{
return Visibility.Collapsed;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo cultureInfo)
{
return null;
}
}
Here is how I referenced the converter on Blend/XAML
<TextBlock Visibility="{Binding QuickProfiles, ConverterParameter=CollapsedOnEmpty, Converter={StaticResource CollectionLengthToVisibility}}">Some Text</TextBlock>
I would use the Enumerable.Any() extension method. It will work on any IEnumerable<T> and avoids you having to know what sort of collection you're dealing with. Since you don't know T you can just use .Cast<object>()
public class CollectionLengthToVisibility : System.Windows.Data.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo cultureInfo)
{
var collection = value as System.Collections.IEnumerable;
if (collection == null)
throw new ArgumentException("value");
if (collection.Cast<object>().Any())
return Visibility.Visible;
else
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo cultureInfo)
{
throw new NotImplementedException();
}
}

Use variable from an instance of a class in a converter?

I have some code as follows:
public partial class MainWindow : Window
{
public bool Adam = true;
public MainWindow()
{
InitializeComponent();
}
public class NextEnabled : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Adam;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return true;
}
}
}
What I want my converter to return is the value of Adam. I understand that it doesn't work right now because the converter class doesn't have a reference to an instance of MainWindow. In the XAML, the main window is named "window_main", and I want to reference this instance - but can't.
Is there any way to do this? Using return window_main.Adam; does not work either - it doesn't recognize this instance.
If you are using only a single instance of your main window, how about making it global? Of course, this is not the best approach, but I truly can't think of any other solution for your problem.
public static class Globals
{
public static MainWindow MainWindow;
}
public partial class MainWindow : Window
{
public bool Adam = true;
public MainWindow()
{
Globals.MainWindow = this;
InitializeComponent();
}
public class NextEnabled : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Globals.MainWindow;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return true;
}
}
}
Make NextEnabled like this
public class NextEnabled : IValueConverter
{
protected Window window_main;
public NextEnabled(Window w) { window_main = w; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return window_main.Adam;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return true;
}
}
You have to call this new constructor when you create NextEnabled.

Categories

Resources