If I change the Binding in Entry.Text using "Style Trigger", the second field is overwritten with the information from the first Binding. In other words, Person.Name is overwritten by Person.Surname
Can you reproduce this behaviour and tell me how can I improve it?
Below is the complete code
Style definition
<Style TargetType="Entry" x:Key="MyStyle">
<Style.Triggers>
<DataTrigger TargetType="Entry" Binding="{Binding Source={x:Reference mySwitch}, Path=IsToggled}" Value="True">
<Setter Property="Text">
<Setter.Value>
<Binding Path="Surname" Mode="TwoWay" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger TargetType="Entry" Binding="{Binding Source={x:Reference mySwitch}, Path=IsToggled}" Value="False">
<Setter Property="Text">
<Setter.Value>
<Binding Path="Name" Mode="TwoWay" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
Target Entry and Switch:
<Label Text="Actual Person.Name" Grid.Row="0" Grid.Column="0" />
<Label Text="{Binding Path=Name}" Grid.Row="0" Grid.Column="1" />
<Label Text="Actual Person.Surname" Grid.Row="1" Grid.Column="0" />
<Label Text="{Binding Path=Surname}" Grid.Row="1" Grid.Column="1" />
<Label Text="Person.Name / Person.Surname" Grid.Row="2" Grid.Column="0" />
<Switch x:Name="mySwitch" Grid.Row="2" Grid.Column="1" />
<Label Text="Change Name/Surname" Grid.Row="3" Grid.Column="0" />
<Entry Style="{StaticResource MyStyle}" Grid.Row="3" Grid.Column="1" />
Code Behind:
public partial class MainPage : ContentPage
{
private Person p = new Person { Name = "Joe", Surname = "Doe" };
public MainPage()
{
InitializeComponent();
BindingContext = p;
}
}
Source:
public class Person : INotifyPropertyChanged
{
private string _surname = "Doe";
public string Surname
{
get => _surname;
set
{
if (value != _surname)
{
_surname = value;
Raise();
}
}
}
private string _name = "Joe";
public string Name
{
get => _name;
set
{
if (value != _name)
{
_name = value;
Raise();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void Raise([CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
---------------------------------------------------------------------------
It seems to me that the problem is with behavior when switching Triggers, because this phenomenon does not occur if I perform a similar test from the code level.
The following example works as expected:
Test Class
public class Test
{
public void Run1()
{
Person p = new Person { Name = "Joe", Surname = "Doe" };
Bindable bindable = new Bindable();
Binding bindingToName = new Binding("Name");
Binding bindingToSurname = new Binding("Surname");
bindable.BindingContext = p;
bindable.SetBinding(Bindable.TextProperty, bindingToName);
bindable.SetBinding(Bindable.TextProperty, bindingToSurname);
bindable.SetBinding(Bindable.TextProperty, bindingToName);
bindable.SetBinding(Bindable.TextProperty, bindingToSurname);
bindable.SetBinding(Bindable.TextProperty, bindingToName);
bindable.SetBinding(Bindable.TextProperty, bindingToSurname);
}
}
Custom BindableObject
public class Bindable : BindableObject
{
public static readonly BindableProperty TextProperty = BindableProperty.Create("Text", typeof(string), typeof(Bindable), "", propertyChanged: MyPropertyChanged);
private static void MyPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
Debug.WriteLine($"Property changed from '{oldValue}' to {newValue}");
}
}
Source
public class Person : INotifyPropertyChanged
{
private string _surname = "Doe";
public string Surname
{
get => _surname;
set
{
if (value != _surname)
{
_surname = value;
Raise();
}
}
}
private string _name = "Joe";
public string Name
{
get => _name;
set
{
if (value != _name)
{
_name = value;
Raise();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void Raise([CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
Run Test
internal class Program
{
private static void Main(string[] args)
{
new Test().Run1();
Console.ReadKey();
}
}
Result (as expected)
Property changed from '' to Joe
Property changed from 'Joe' to Doe
Property changed from 'Doe' to Joe
Property changed from 'Joe' to Doe
Property changed from 'Doe' to Joe
Property changed from 'Joe' to Doe