Winrt IValueConverter on a GridView item - c#

I have a ObservableCollection<TimeSpan> Laps which I am databinding to a gridview. This works as expected but I need to apply a converter to set the format of the TimeSpan:
In my resources:
<utils:TimeToStringConverter x:Key="myConverter"/>
My Gridview:
<GridView HorizontalAlignment="Left" Height="278" Margin="78,220,0,0" VerticalAlignment="Top" Width="1278" ItemsSource="{Binding model.Laps}" />
I have the following converter which I want to apply on the items of a GridView / ListView in Winrt:
public class TimeToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
TimeSpan t = (TimeSpan) value;
return t.ToString(#"hh\:dd\:ss\.fff");
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
I can't figure out how to get the converter to work, and when I apply it on the GridView then it is looking for me to convert an Observable collection rather than just a TimeSpan item. What should I do here ?
Regards

You need something like a
<GridView
...>
<GridView.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding Converter={StaticResource myConverter}}" />
</DataTemplate>
</GridView.ItemTemplate>

Use the below modified line
I've just modified the item source like below
ItemsSource="{Binding model.Laps,Converter={StaticResource myConverter}}"
<GridView HorizontalAlignment="Left" Height="278" Margin="78,220,0,0" VerticalAlignment="Top" Width="1278" ItemsSource="{Binding model.Laps,Converter={StaticResource myConverter}}" />

Related

Able to add Text to a textblock after binding?

so i've a Textblock that binds a property using the (Text="x"), but is there a way to add more text to it?
So this is the line in XAML
<TextBlock Name="UpdatedStock" FontSize="12" Text="{x:Bind Stock, Mode=TwoWay}" HorizontalAlignment="Left" />
and it only says the number of Stock atm, but i want it to say "X in stock". But i cant add more text to it, is there a way somehow to add it on the same line or i have to do it somewhere else?
Kinds regards
Able to add Text to a textblock after binding?
You have many ways to approach. In general we often add new TextBlock with static text X and place left of UpdatedStock
<RelativePanel>
<TextBlock
x:Name="UpdatedStock"
FontSize="12"
RelativePanel.AlignLeftWithPanel="True"
Text="{x:Bind Stock, Mode=OneWay}" />
<TextBlock Margin="2,0,0,0"
FontSize="12"
RelativePanel.RightOf="UpdatedStock"
Text="X" />
</RelativePanel>
And the other way is use IValueConverter to append X to Stock propety.
public class StringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
if (value == null)
return null;
return value.ToString()+ "X";
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
Usage
<Page.Resources>
<local:StringConverter x:Key="StrConverter" />
</Page.Resources>
<Grid>
<TextBlock
x:Name="UpdatedStock"
FontSize="12"
RelativePanel.AlignLeftWithPanel="True"
Text="{x:Bind Stock, Mode=OneWay, Converter={StaticResource StrConverter}}" />
</Grid>

WPF - Conditional binding in ItemsControl

I'm very new to WPF, and am just getting started with data binding. What I'd like to do is generate a list of checkboxes based on a list in my view model. The XAML I have at the moment is:
<ItemsControl ItemsSource="{Binding Path=TestList, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Path=Name}" IsChecked="{Binding Path=Enabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10,5,10,5" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This works correctly, and generates a checkbox for every item in TestList. What I'd like to do is only generate checkboxes for items where the condition TestList[i].Type == "Mode" is true. I believe that I may need to use a <DataTrigger> element, but I don't know the details of how to do this.
[EDIT] Just to clarify, each element of TestList has Name, Enabled, and Type properties.
There are several ways to do this. However, the simplest static approach would be to just filter it at your ViewModel
Filtered = new ObservableCollection(TestList.Where(x => x.Type == "Mode"));
...
<ItemsControl ItemsSource="{Binding Path=Filtered , UpdateSourceTrigger=PropertyChanged}">
Note : There are fancier more dynamic ways to achieve this, though this might help you out
As I guess that you want to make the checkbox appear if TestList.Type changes, I would suggest make a Converter and Bind it to the CheckBox Visibility.
public sealed class CheckBoxVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null || parameter == null)
return Visibility.Visible;
var type = (string)value;
var condition = (string)parameter;
return type.Equals(condition) ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
And then in the dictionary add the reference to your namespace
xmlns:converters="clr-namespace:Projct.Converters;
and in the resources dictionary
<converters:CheckBoxVisibilityConverter x:Key="CheckBoxConverter"/>
Finally in the xaml
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox
Margin="10,5,10,5"
Content="{Binding Path=Name}"
IsChecked="{Binding Path=Enabled, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="{Binding Path=Type, Converter={StaticResource CheckBoxConverter}, ConverterParameter=Mode}" />
</DataTemplate>
</ItemsControl.ItemTemplate>

How to implement a converter in WP8 using XAML and C# for capitalize the first letter of a word in a TexBlock?

I have a data template with a TexBlock in XAML. This TexBlock shows a word in a word list. Every word I want to put the first letter capitalized, because all words are in lowercase.
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="AddrBookItemTemplate">
<StackPanel VerticalAlignment="Top">
<TextBlock Margin="5,0,0,0" FontSize="20" Text="{Binding name}" />
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
In c# implement the converter
namespace Converter.ViewModels
{
public class ToCapitalizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return char.ToUpper(value.ToString()[0]) + value.ToString().Substring(1);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (value as string).ToLower();
}
}
}
In App.xaml
...
xmlns:vm="clr-namespace:Converter.ViewModels"
<Application.Resources>
<vm:ToCapitalizeConverter x:Key="ToCapitalizeConverter"/>
</Application>
In MainPage.xaml
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="AddrBookItemTemplate">
<StackPanel VerticalAlignment="Top">
<TextBlock Margin="5,0,0,0" FontSize="20" Text="{Binding name, Converter={StaticResource ToCapitalizeConverter}}" />
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
You can use a converter as follows:
<TextBlock Margin="5,0,0,0" FontSize="20" Text="{Binding name, Converter ={StaticResource myConverter}}" />
Specific information on how to implement a converter can be found here. You can essentially perform any operation you like on the text. I actually like Humanizer to do these type of text conversions.

Convert string to int using IValueConverter

How do I convert string values to integers and back using IValueConverter?
I have a database that consists of two tables; table CompanyX and table DeptY.
Table CompanyX has field ID(int), firstName, lastName, Email, Phone.
Table DeptY has field pID(int), Roles.
DeptY pID is foreign key To CompanyX ID. Every time I select someone in the Combobox, I want it to display as their ID in a DataGrid.
This is my ItemTemplate below:
<Application.Resources>
<DataTemplate x:Key="myTemplate">
<WrapPanel HorizontalAlignment="Stretch">
<TextBlock Text="{Binding FirstName}"/>
<Label />
<TextBlock Text="{Binding LastName}"/>
</WrapPanel>
</DataTemplate>
</Application.Resources>
This is my Combobox which is bound to the ItemTemplate:
<ComboBox Height="23" HorizontalAlignment="Right" Margin="0,90,267,0"
Name="comboID" ItemsSource="{Binding}" VerticalAlignment="Top"
Width="208" ItemTemplate="{StaticResource myTemplate}" />
And a DataGrid which displays:
<DataGridTemplateColumn x:Name="pIDColumn" Header="Person ID" Width="auto">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=pID, Converter= {StaticResource myConverter}}"/>
<DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn x:Name="rolesColumn" Header="Roles" Width="auto" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Roles}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
IValueConverter which is not converting!!
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string a = (string)value;
int b;
int.TryParse(a, out b);
return b;
}
public object ConvertBack(object value, Type targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
You are converting the wrong way around. Convert() takes the binding source as input (int in your case), and outputs what the xaml is expecting (string).
But you don't even need a converter. You can bind straight to an int and WPF will automatically call ToString() on it to display it as text.
Like was said in the other answer, you are doing it backwards. The Convert side of an IValueConverter is meant for converting from the source property to what is in the bound element, in your case a textbox. You need to do your parsing on the ConvertBack side because that is what takes what is in the textbox (a string) and converts it back to a number.
public class IntToString : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value.ToString();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
int ret = 0;
return int.TryParse((string)value, out ret) ? ret : 0;
}
}

Binding DataGrid's FontWeight property to value converter

I'm trying to make cell bold or normal if item new/old inside DataGrid but stumbled upon erro..
Looks like my issue described here: Why can I not bind the Visiblity of a DataGridTemplateColumn in Silverlight 4?
I'm getting following error:
Object of type 'System.Windows.Data.Binding' cannot be converted to
type 'System.Windows.FontWeight'.
And my XAML looks like so:
<sdk:DataGridTextColumn Header="Subject" Binding="{Binding Subject}" CanUserReorder="True" CanUserResize="True" CanUserSort="True" Width="Auto" FontWeight="{Binding IsNew, Converter={StaticResource BoolToFontWeightConverter}}" />
My question is there any workaround to get this working? I'm not even using template column, it's plain text column..
public class BoolToFontWeightConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((bool)value) ? FontWeights.Bold : FontWeights.Normal;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (FontWeight)value == FontWeights.Bold;
}
}
The FontWeight property of the DataGridTextColumn is not a dependency property and thus will not support bindings. A workaround would be to use a DataGridTemplateColumn with a TextBox as the DataTemplate and set the appropriate bindings there, something like:
<sdk:DataGridTemplateColumn Header="Subject"
CanUserReorder="True"
CanUserResize="True"
CanUserSort="True"
Width="Auto">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Subject}" FontWeight="{Binding IsNew, Converter={StaticResource BoolToFontWeightConverter}}"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>

Categories

Resources