Reputation: 31343
I have a simple composed custom control that displays text set to a bound ControlText
property. In the example below, you can see when the button is clicked the control is updated.
How can I change the code so that the label shown by the control takes whatever is sent to it and converts it to all uppercase?
So instead of showing...
Count=5
it would show...
COUNT=5
In this simple example an IValueConverter can be leveraged to accomplish this, but I want to see a different implementation for a much more complex example I need to implement. I am seeking a solution that intercepts the value being set in the code behind, converts it, and sets it to the ControlText property of the custom control.
SimpleControl.xaml.cs
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SimpleControl : ContentView
{
public SimpleControl ()
{
InitializeComponent ();
}
public static readonly BindableProperty ControlTextProperty = BindableProperty.Create(
propertyName: nameof(ControlText),
returnType: typeof(string),
declaringType: typeof(SimpleControl),
defaultBindingMode: BindingMode.TwoWay,
defaultValue: "Hello World");
public string ControlText
{
get { return (string)base.GetValue(ControlTextProperty); }
set { base.SetValue(ControlTextProperty, value); }
}
}
Also, I would expect at runtime this breakpoint to be hit, but the code never stops on it. I am setting the property from the SimplePageModel, so I find it strange this is never hit. Can someone explain that to me as well?
SimpleControl.xaml
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App7.SimpleControl"
x:Name="this">
<ContentView.Content>
<StackLayout Margin="100">
<Label Text="{Binding Source={x:Reference this}, Path=ControlText}" />
</StackLayout>
</ContentView.Content>
</ContentView>
SimplePage.xaml
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App7"
x:Class="App7.SimplePage">
<ContentPage.Content>
<StackLayout>
<local:SimpleControl ControlText="{Binding ControlText}" />
<Button Text="Update Control"
Command="{Binding UpdateControl}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
SimplePageModel.cs (leveraging FreshMVVM)
public class SimplePageModel : FreshBasePageModel
{
public SimplePageModel() { }
private int _index;
public string ControlText { get; set; }
public Command UpdateControl
{
get
{
return new Command((t) =>
{
ControlText = $"Count = {++_index}";
});
}
}
public override void Init(object initData)
{
ControlText = $"Count = 0";
base.Init(initData);
}
}
Upvotes: 3
Views: 335
Reputation: 6502
Direct answer to the question : change the definition of your property from
public static readonly BindableProperty ControlTextProperty = BindableProperty.Create(
propertyName: nameof(ControlText),
returnType: typeof(string),
declaringType: typeof(SimpleControl),
defaultBindingMode: BindingMode.TwoWay,
defaultValue: "Hello World");
to
public static readonly BindableProperty ControlTextProperty = BindableProperty.Create(
propertyName: nameof(ControlText),
returnType: typeof(string),
declaringType: typeof(SimpleControl),
defaultBindingMode: BindingMode.TwoWay,
defaultValue: "Hello World",
coerceValue: (bindable, value) =>
{
if (value!=null)
return ((string) value).ToUpper();
return value;
});
Upvotes: 0
Reputation: 787
You can also use triggers for this purpose, since its not too clear what is the idea in the background, I am just suggesting that it can be helpful: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/triggers
Upvotes: 0