Image Converter not working in Xamarin.Forms - c#

Im using the converter to change the image but image is not loading here can somebody please help me here what I'm done wrong? I had checked the converter by debugging it is not getting hit.
Converter Code:
public class DownloadIconConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return ((bool)value) ? "progressicon.png" : "cloud_download.png";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
In Xaml
<ContentPage.Resources>
<converter:DownloadIconConverter x:Key="downloadiconconverter" />
</ContentPage.Resources>
<ImageButton
HeightRequest="40"
IsVisible="True"
Source="{Binding DownloadIcon,Converter={StaticResource downloadiconconverter}}"
WidthRequest="35" Command ="{Binding BindingContext.Download, Source={x:Reference listview}}" CommandParameter="{Binding .}" />
In Code behind file
public bool DownloadIcon
{
get { return downloadicon; }
set { SetProperty(ref downloadicon, value); }
}

The Binding in my knowledge is not working because the boolean is in the ViewModel and not accessible to the listview data template
Try using this:
Source="{Binding BindingContext.DownloadIcon, Converter={StaticResource downloadiconconverter},Source={x:Reference listview}}"

Related

Why is IValueConverter ConverterParameter not Bindable? [duplicate]

In Xamarin Forms I'm trying to create a xaml converter with properties.
This is to be used, for example, to show values from a list in different ways, based on a code behind property.
I based my code on this: https://stackoverflow.com/a/29869734.
Converter:
namespace App2.Converters
{
class MyConverter : IValueConverter
{
public int ConvParam { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return $"value: {value} - ConvParam: {ConvParam}";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
XAML:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:conv="clr-namespace:App2.Converters"
x:Class="App2.MainPage"
x:Name="MainPageXaml">
<ContentPage.Resources>
<conv:MyConverter x:Key="cnv" ConvParam="{Binding Source={Reference MainPageXaml}, Path=PropParam}" />
<!--<conv:MyConverter x:Key="cnv" ConvParam="333" />-->
</ContentPage.Resources>
<StackLayout Orientation="Vertical">
<!-- Place new controls here -->
<Label Text="{Binding Source={Reference MainPageXaml}, Path=PropVal}" />
<Label Text="{Binding Source={Reference MainPageXaml}, Path=PropParam}" />
<Label Text="{Binding Source={Reference MainPageXaml}, Path=PropVal, Converter={StaticResource cnv}}" />
</StackLayout>
Code behind:
public partial class MainPage : ContentPage
{
public int PropVal { get; set; } = 111;
public int PropParam { get; set; } = 222;
public MainPage()
{
InitializeComponent();
}
}
The goal is to bind ConvParam of my converter to PropParam in code behind.
But if I use:
<conv:MyConverter x:Key="cnv" ConvParam="{Binding Source={Reference MainPageXaml}, Path=PropParam}" />
the error Position 10:39. No property, bindable property, or event found for 'ConvParam', or mismatching type between value and property is shown and the app doesn't compile.
The property ConvParam itself is recognized inside xaml: if I replace the above line with
<conv:MyConverter x:Key="cnv" ConvParam="333" />
everything works.
The binding expression I used ({Binding Source={Reference MainPageXaml}, Path=PropParam}) actually works, if used as source for the text property of a label:
<Label Text="{Binding Source={Reference MainPageXaml}, Path=PropParam}" />
But if I use it in Resources, It doesn't work.
Thanks to Julipan I could make it work!
As he pointed out, ConvParam must be a BindableProperty, so I modified my converter to inherit from BindableObject and defined ConvParam as BindableProperty.
Converter:
namespace App2.Converters
{
class MyConverter : BindableObject, IValueConverter
{
public static readonly BindableProperty ConvParamProperty = BindableProperty.Create(nameof(ConvParam), typeof(int), typeof(MyConverter));
public int ConvParam
{
get { return (int)GetValue(ConvParamProperty); }
set { SetValue(ConvParamProperty, value); }
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return $"value: {value} - ConvParam: {ConvParam}";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

How to split a string and insert it into Binding in the DataTemplate

I have a DataTemplate of an acollectionView, inside I have a Label with the Text in Binding property.
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid BackgroundColor="Gray" Opacity="0.8" RowSpacing="0.1">
<Label TextColor="White" Text="{Binding Data}"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
I would need to be able to split that string into multiple strings, and I was able to find this code
public class DelimiterConverter : IValueConverter
{
public object Convert(Object value, Type targetType, object parameter, CultureInfo culture)
{
string[] values = ((string)value).Split(' ');
int index = int.Parse((string)parameter);
return values[index];
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return "";
}
}
HumorDiary[] note = JsonConvert.DeserializeObject<HumorDiary[]>(textt);
DelimiterConverter conv = new DelimiterConverter();
foreach (HumorDiary hd in note)
{
conv.Convert(hd.Data, typeof(string), " ", CultureInfo.CurrentCulture);
}
I don't know if I have entered everything right, but I would not know how to obtain the various strings divided into several parts, in the DataTemplate
It could be used like this:
Add the namespace where your converter is to you page
xmlns:converters="clr-namespace:MyApp.Converters"
Add the converter to your page's resources
<ContentPage.Resources>
<converters:StringSplitConverter x:Key="StringSplitConverter" />
</ContentPage.Resources>
Edit the CollectionView's ItemTemplate to display all the separated strings in separate labels (using BindableLayout)
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid BackgroundColor="Gray" Opacity="0.8" RowSpacing="0.1">
<!-- Bind the ItemsSource to the Data using the converter -->
<StackLayout BindableLayout.ItemsSource="{Binding Data, Converter={StaticResource StringSplitConverter}}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<!-- Display the separated word -->
<Label Text="{Binding .}" />
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
This is the converter. Takes the string and splits it by spaces
public class StringSplitConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string stringValue)
{
return stringValue.Split(' ');
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

IValueConverter returning as object not value that is expected

I'm trying to convert a string on a label (or anything) to another string. This is for Icon fonts.
Converter
[ValueConversion(typeof(string), typeof(string))]
public class StringToIconConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string property = ((string)value).ToLower();
switch (property)
{
case "maximize": return #"\e901";
default return property;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
...
}
Then I've added it to my pages that need it
<Helpers:StringToIconConverter x:Key="Icon" />
And this is how I'm setting it
<Button Style="{StaticResource NavButton}"
Tag="Document"
Command="{Binding GotoDataMatrixEnterCommand}">
<Button.Content>
<Label Content="{Binding Source={RelativeSource Self},
Path=Tag,
Converter={StaticResource Icon},
UpdateSourceTrigger=LostFocus}"
Tag="Document" />
</Button.Content>
</Button>
And what I'm getting is
Windows.System.Control.Label in its place. Am I not converting it properly, I'm not quite sure why it is not replacing the correct information. I've tried a few things, and reading up online though I'm stuck at the moment. Plus when I try to debug it doesn't work (it never hits the breakpoints)
The problem is with the Binding on Label.Content. You should use RelativeSource, not Source.
It should be:
RelativeSource={RelativeSource Mode=Self}
Also, you have a syntactic error in the switch statement of StringToIconConverter: default return property; should be default: return property; (you're missing a colon).

How to make WPF AutoCompleteBox accept more than one Property for filtering

I want to search in multiple fields in AutoCompleteBox, I want to search in ClientName if the user starts typing characters, and search in ClientNumber if the user starts typing numbers.
I searched on the internet and from this Answer I understand that I should use Converter to accomplish what I want, But unfortunately, they do not explain how can I write the converter!
This is the AutoCompleteBox
<toolkit:AutoCompleteBox x:Name="txbClientName" FilterMode="StartsWith" IsTextCompletionEnabled="True"
ItemsSource="{Binding ocClients}"
ValueMemberBinding="{Binding Converter= {StaticResource ClientSearch}}"
SelectedItem="{Binding ElementName=this,
Path=ContactPerson,
Mode=TwoWay,
UpdateSourceTrigger=LostFocus}" PreviewKeyUp="txbClientName_PreviewKeyUp" LostFocus="txbClientName_LostFocus">
<toolkit:AutoCompleteBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding ContactPerson}"/>
</StackPanel>
</DataTemplate>
</toolkit:AutoCompleteBox.ItemTemplate>
What should the ClientSearch Converter do ??
public class ClientSearchConverter : IValueConverter
{
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//What should I write here !!!
}
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
Any help, please!

Binding to last array element

So far, i have an ObservableCollection<T> for objects.
I always want to display the last inserted element into a TextBlock. I implemented two solutions in XAML, but both not working:
<TextBlock Text="{Binding Path=entries.Last().message, FallbackValue=...}" />
<TextBlock Text="{Binding Path=entries[entries.Length-1].message, FallbackValue=...}" />
This one works, but references the first entry:
<TextBlock Text="{Binding Path=entries[0].message, FallbackValue=...}" />
Am i missing something? Is it possible to do with pure XAML?
Solution 1 :
You can use a custom converter to achieve this :
Converter class :
class LastItemConverter : IValueConverter
{
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
IEnumerable<object> items = value as IEnumerable<object>;
if (items != null)
{
return items.LastOrDefault();
}
else return Binding.DoNothing;
}
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
Xaml :
<Application.Resources>
<local:LastItemConverter x:Key="LastItemConverter" />
</Application.Resources>
<TextBlock Text="{Binding Path=entries, Converter={StaticResource LastItemConverter}}" />
Solution 2 :
The other way is to create a new property in your model that returns the entry :
public Object LastEntry => entries.LastOrDefault();
Xaml :
<TextBlock Text="{Binding Path=LastEntry, ... " />

Categories

Resources