I have one label and two entries. I want to make the label display the selected entry. Right now selecting the second entry does not change the label. What is the culprit?
Here is my code.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:MyProject"
x:Class="MyProject.TestPage"
x:DataType="vm:TestViewModel"
Title="TestPage">
<VerticalStackLayout>
<Entry x:Name="Entry1" Text="Entry 1">
<Entry.GestureRecognizers>
<TapGestureRecognizer Command="{Binding SetSelectedEntryCommand}"
CommandParameter="{Reference Entry1}" />
</Entry.GestureRecognizers>
</Entry>
<Entry x:Name="Entry2"
Text="Entry 2">
<Entry.GestureRecognizers>
<TapGestureRecognizer Command="{Binding SetSelectedEntryCommand}"
CommandParameter="{Reference Entry2}" />
</Entry.GestureRecognizers>
</Entry>
<Label Text="{Binding SelectedEntry.Text}" />
</VerticalStackLayout>
</ContentPage>
public partial class TestPage : ContentPage
{
public TestPage(TestViewModel model)
{
InitializeComponent();
BindingContext = model;
model.InitializeCommand.Execute(Entry1);
}
}
It is annoying: It looks like your post is mostly code; please add some more details.
public partial class TestViewModel : ObservableObject
{
[ObservableProperty]
Entry _selectedEntry;
[RelayCommand]
void Initialize(Entry selectedEntry)
{
SelectedEntry = selectedEntry;
SelectedEntry.BackgroundColor = Colors.Pink;
}
[RelayCommand]
void SetSelectedEntry(Entry selectedEntry)
{
SelectedEntry.BackgroundColor = Colors.White;
SelectedEntry = selectedEntry;
SelectedEntry.BackgroundColor = Colors.Pink;
}
}
Apparently it works on Android but it does NOT work on Windows. Because I need a touch screen on Windows?
A variation @FreakyAli's answer, you can bind to the IsFocused property and use it in a DataTrigger as follows. This would minimize the amount of work your View Model needs to do since you can implement all the requirements in the View only, e.g.
<VerticalStackLayout Padding="30,0" Spacing="25">
<Entry x:Name="Entry1" Text="Entry 1" />
<Entry x:Name="Entry2" Text="Entry 2" />
<Label x:DataType="Entry" Text="{Binding Text, Source={Reference Entry1}}">
<Label.Triggers>
<DataTrigger
x:DataType="Entry"
Binding="{Binding IsFocused, Source={Reference Entry2}}"
TargetType="Label"
Value="True">
<Setter x:DataType="Entry" Property="Text" Value="{Binding Text, Source={Reference Entry2}}" />
</DataTrigger>
</Label.Triggers>
</Label>
</VerticalStackLayout>
I do have a CommunityToolkit MultiMathExpressionConverter enhancement that has a simple XAML solution that helps solve your problem at increasing scale, e.g. for 3 Entry fields:
<VerticalStackLayout Padding="30,0" Spacing="25">
<Entry x:Name="Entry1" Text="Entry 1" />
<Entry x:Name="Entry2" Text="Entry 2" />
<Entry x:Name="Entry3" Text="Entry 3" />
<Label Text="{MultiBinding {Binding Text, Source={Reference Entry1}},
{Binding IsFocused, Source={Reference Entry2}},
{Binding Text, Source={Reference Entry2}},
{Binding IsFocused,Source={Reference Entry3}},
{Binding Text, Source={Reference Entry3}},
Converter={StaticResource MultiMathExpressionConverter},
ConverterParameter='x1 and x2 or x2 and x3 or x0'}" />
</VerticalStackLayout>
The above is based on being able to write the Label.Text expression as:
Label.Text = Entry2.IsFocused && Entry2.Text
|| Entry3.IsFocused && Entry3.Text
|| Entry1.Text
Or you could do something more conventional such as ConverterParameter='x1 ? x2 : x3 ? x4 : x0'
which means:
Label.Text = Entry2.IsFocused
? Entry2.Text
: Entry3.IsFocused
? Entry3.Text
: Entry1.Text
Help me out by voting on it: