I'm going crazy with converters. I know that I must use it to change the "exit value" of my values, when needed, but I don't know how to use right for my case.
I have my simple MVVM (3 fields only) and my main window with a list of my items. The first item is calculated depending on a function, and can show YES or NOT, the other values are binded directly.
This is working well, but I need to change the background and foreground colors depending on the YES or NOT value I have in the first calculated field. For example:
YES (must be blue) - ITEM 1
NO (must be grey) - ITEM 2
YES (must be blue) - ITEM 3
While the internal values in my database are (in this case the calc is modulus):
2 - ITEM 1
3 - ITEM 2
4 - ITEM 3
My ListBox code is this:
<phone:PhoneApplicationPage
x:Class="Pasti.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="My App" Style="{StaticResource PhoneTextNormalStyle}" />
<TextBlock Text="My List" Style="{StaticResource PhoneTextTitle1Style}" />
</StackPanel>
<ListBox x:Name="lstPills" Grid.Row="1" ItemsSource="{Binding AllItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch" Width="440">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Background="HERE MUST GO THE CONVERTER, I SUPOSE">
<TextBlock Text="{Binding IsPair, Mode=TwoWay}"/>
</Border>
<TextBlock
Text="{Binding Name}"
FontSize="{StaticResource PhoneFontSizeLarge}"
Grid.Column="1"
VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</phone:PhoneApplicationPage>
And the CS code is this for this page:
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
// Set the page DataContext property to the ViewModel.
this.DataContext = App.ViewModel;
}
}
For the calculated field, I added this to the Model (_myNumber holds the value I must check):
// Define a custom field based on some database values
// Get is calculated, while set will force it to refresh by Notifying
public string IsPair
{
get
{
return _myNumber % 2 == 0 ? "YES" : "NO";
}
set
{
NotifyPropertyChanged("IsPair");
}
}
NOTE: Because I don't know other way to force the list to refresh, I put the set property to only notify and the TwoWay Mode, and I just do a IsPair = ""
when I want it to recalculate. If there are other way to do it, will be welcome.
So, with this info, how can I made a Converter that, based on my IsPair value, set the Background
property of the Border to Blue or Grey? I saw a lot of Converter examples, but still don't get the point to do exactly this.
I suppose I must put something like this in the MainPage.cs, under the MainPage Class:
// Converter for the YES-NO column on the list
public class IsPairConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (MY_CALCULATED_VALUE == "YES")
return "Blue";
return "Grey";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
But how to get the MY_CALCULATED_VALUE, and how to set the converter in the Background
value of the Border?
So close!
First, bind the background to
IsPair
and use the converter:In your converter, create a brush depending on the value:
And you're done.
If you want the value to be computed only one time, instead of every time
IsPair
is called, you can do the computation in the setter ofMyNumber
and assign it toIsPair
: