Binding property to control - avaloniaui

How do I bind SourceObject and TargetObject to the TextBox-Element?
This works, but I want more than one textbox and that does not seem to be possible when they are named the same.
My goal is to have the TextBox change its background color when focused.
<TextBox xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
xmlns:ia="clr-namespace:Avalonia.Xaml.Interactions.Core;assembly=Avalonia.Xaml.Interactions"
x:Class="Test.View.CustomTextBox"
Name="textBox">
<i:Interaction.Behaviors>
<ia:EventTriggerBehavior EventName="GotFocus" SourceObject="{Binding #textBox}">
<ia:ChangePropertyAction TargetObject="{Binding #textBox}" PropertyName="Background" Value="{StaticResource FocusedBackgroundColor}"/>
</ia:EventTriggerBehavior>
</i:Interaction.Behaviors>
</TextBox>
Thanks a lot!

You can use RelativeSource and converter, something like that:
public class BoolColorBrushConverter : IValueConverter
{
public Brush TrueBrush {get;set;}
public Brush FalseBrush {get;set;}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value is bool b && b)
return TrueBrush;
else
return FalseBrush;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotSupportedException();
}
xaml:
<MyControl>
<MyControl.Resources>
<BoolBrushConverter TrueColor="Red" FalseColor="Blue" x:Key="TextBoxFocusedBackgroundConverter"/>
</MyControl.Resources>
<TextBox Background="{Binding IsFocused, RelativeSource={RelativeSource Self}, Converter={StaticResource TextBoxFocusedBackgroundConverter}}}"/>;
</MyControl>

Related

Converter is called twice, second time with null value

I am writing a MAUI app. I am trying to use a converter. But for some reason, the converter is called twice, and that makes the app crash. Here is the code:
xaml:
<Picker Title="Choose Tile Thickness..."
ItemsSource="{Binding TileThicknessesMetric}"
ItemDisplayBinding="{Binding Value}"
SelectedItem="{Binding SelectedTileThickness}"
IsVisible="{Binding SelectedUnit, Converter={converters:SelectedUnitToBoolShowMetricConverter}, Mode=TwoWay}"
Style="{StaticResource PickerStyle}"
Grid.Row="2" Grid.Column="1" />
Converter:
class SelectedUnitToBoolShowMetricConverter : IValueConverter, IMarkupExtension
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((Unit)value).Code == UnitCode.Metric;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
public object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
As I mentioned, Convert() is called twice, and the second time value is null, which causes a null reference exception. I cannot figure out why it is called the second time.
The same code works as expected in a Xamarin.Forms app.

Set IsVisible property by a string value of model

I am using XAML to define a ListView, with multiple buttons for each cell.
I want to trigger visibility depending on whether a string value is empty or not.
My button inside the ListView is:
<Button Text="{Binding Phone}"
Clicked="OnPhoneClicked"
CommandParameter="{Binding Telefono}"
x:Name="btnPhone" />
Binding Phone is read from my model. It is correctly shown.
How can set a IsVisible property button if Phone's value is an empty string?
Try this code
<Button Text="{Binding Phone}"
Clicked="OnPhoneClicked"
CommandParameter="{Binding Telefono}"
x:Name="btnPhone"
IsVisible="{Binding Phone,Converter={StaticResource StringNullOrEmptyBoolConverter"} />
StringNullOrEmptyBoolConverter.cs file
public class StringNullOrEmptyBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var s = value as string;
return !string.IsNullOrWhiteSpace(s);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Finally add this in App.xaml file
<Application.Resources>
<ResourceDictionary>
<Converter:StringNullOrEmptyBoolConverter x:Key="StringNullOrEmptyBoolConverter" />
</ResourceDictionary>
</Application.Resources>

XAML TextBox - IValueConverter ConvertBack is not called

I have a TextBox bound to a Converter. Convert ist working fine, ConvertBack is never called.
Shouldn't ConvertBack be called after the TextBox.TextChanged Event ?
Following Code is a simplified example of my problem.
<Window.Resources>
<converter:Converter x:Key="MyConverter"/>
</Window.Resources>
<StackPanel>
<TextBox Name="TestTextBox" VerticalAlignment="Top" Margin="10"
Text="{Binding Path=.,
Converter={StaticResource MyConverter},
ConverterParameter=Name,
UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay}" />
</StackPanel>
Simple ValueConverter
public class Converter : IValueConverter
{
public object Convert(object value, Type targetType, object
parameter, CultureInfo culture)
{
return "Yeahhhh";
}
public object ConvertBack(object value, Type targetType, object
parameter, CultureInfo culture)
{
return "F#*ยง";
}
}

Windows Store App Collapse TextBlock if value is null using Style.xaml

If style definition is:
<Style x:Key="BodyTextStyle" TargetType="TextBlock" BasedOn="{StaticResource BaselineTextStyle}">
<Setter Property="FontWeight" Value="SemiLight"/>
</Style>
How do I add property that would collapse the TextBlock if the value is null?
Thanks.
<TextBlock Visibility="{Binding RelativeSource={RelativeSource Self}, Path=Text,
Converter={StaticResource TextIsNullOrEmptyToVisibilityConverter}}"/>
Then, create a IValueConverter named TextIsNullOrEmptyToVisibilityConverter which takes in a string and returns a Visibility enum based on string.IsNullOrEmpty.
Thanks to Nate for his input. The final solution is shown below.
First create the converter.
public class TextIsNullOrEmptyToVisibilityConverter : IValueConverter
{
public object IValueConverter.Convert(object value, System.Type targetType, object parameter, string language)
{
string Str = (string)value;
if (string.IsNullOrEmpty(Str)) {
return Visibility.Collapsed;
} else {
return Visibility.Visible;
}
}
public object IValueConverter.ConvertBack(object value, System.Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
Give the converter a resource key in the page XAML file.
<Page.Resources>
<local:TextIsNullOrEmptyToVisibilityConverter x:Key="visiblityConverter"/>
</Page.Resources>
Apply the resource to the Visibility Attribute as by Nate above.
<TextBlock Visibility="{Binding RelativeSource={RelativeSource Self}, Path=Text,
Converter={StaticResource TextIsNullOrEmptyToVisibilityConverter}}"/>

slider control and textblock control interaction-Metro apps

i am trying to set the slider control to value from text block's text property through {Binding} on XAML.
<Slider ValueChanged="slider_ValueChanged_1" Value= "{Binding ElementName=ComponentTextBlockValue,Path=Text}" StepFrequency="25"/>
Do i need an converter to set the slider's value . The binding seems to work sometimes but sometimes it doesn't work. Sometimes,the slider just doesn't set its value to text block value.
Since you bind the Slider's value directly without a value converter, I suspect that the binding is broken when the text is not a number or out of range.
You can prevent that by creating a value converter that will prevent bad value to be bound, so the binding will always work.
Here is some example:
public class TextToSliderValueConverter : IValueConverter
{
public double MaximumSliderValue { get; set; }
public double MinimumSliderValue { get; set; }
public object Convert(object value, Type targetType, object parameter, string language)
{
double sliderValue;
if (double.TryParse(value as string, out sliderValue)
&& sliderValue <= MaximumSliderValue && sliderValue >= MinimumSliderValue)
{
return sliderValue;
}
else
{
return 0.0;
}
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
Here is the XAML:
<Page
x:Class="stovfSliderTextBox.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:stovfSliderTextBox"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<local:TextToSliderValueConverter x:Key="txtToSliderValue" MaximumSliderValue="100" MinimumSliderValue="0"/>
</Page.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<Slider Value= "{Binding ElementName=ComponentTextBlockValue,Path=Text, Converter={StaticResource txtToSliderValue}, ConverterParameter=slider}" StepFrequency="25"/>
<TextBox x:Name="ComponentTextBlockValue" Width="50"/>
</StackPanel>
</Grid>
</Page>
The TextToSliderValueConverter makes sure that the slider will always get the valid value. If you do not use default Slider.Maximum or Slider.Minimum, you can modify the values accordingly.
Hope this helps!