.Net Maui adding a Behavior to a Style

415 Views Asked by At

In my app I have many Entry controls on multiple pages. I also have a behavior 'EntryHighlightBehavior' that simply highlights the control and the label that identifies it. This works as expected. I also have a StaticResource that gives them consistent formatting. I would like to identify the behavior inside the element of my style so that I don't have to enumerate it each time I create a new Entry. I looked at this post Style target behaviors MAUI but it creates a command which I'm not looking to do. So any Help would be appreciated. Relevant code below: EntryHighlightBehavior

    public class EntryHighlightBehavior : Behavior<Entry>
{
    protected override void OnAttachedTo(Entry entry)
    {
        entry.Focused += OnEntryFocusChanged;
        entry.Unfocused += OnEntryFocusChanged;
        base.OnAttachedTo(entry);
    }

    protected override void OnDetachingFrom(Entry entry)
    {
        entry.Focused -= OnEntryFocusChanged;
        entry.Unfocused -= OnEntryFocusChanged;
        base.OnDetachingFrom(entry);
    }

    void OnEntryFocusChanged(object sender, FocusEventArgs e)
    {
        var myentry = sender as Entry;
        var myGrid = myentry.Parent as Grid;
        if (e.IsFocused)
            myGrid.BackgroundColor = App.HighlightColor;
        else
            myGrid.BackgroundColor = Colors.White;
    }

}

Xaml:

                    <Grid x:Name="grdCustomOptions" ColumnDefinitions="235,*" RowDefinitions="40,40" Grid.Row="2" Grid.ColumnSpan="2" IsVisible="false">
                    <Label x:Name="lblCustomoption" Text="Custom Option" Style="{StaticResource LabelEntry}" Grid.ColumnSpan="2" />
                    <Entry x:Name="entCustomoption" Placeholder="Custom Option" Style="{StaticResource EntryPlain}"
                               ReturnType="Next" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" WidthRequest="400" >
                        <Entry.Behaviors>
                            <behave:EntryHighlightBehavior/>
                        </Entry.Behaviors>
                    </Entry>                        
                </Grid>

StaticResource (Style.xaml):

    <Style x:Key="EntryPlain" TargetType="Entry">
    <Setter Property="HeightRequest" Value="40"/>
    <Setter Property="Keyboard" Value="Plain"/>
    <Setter Property="ReturnType" Value="Done"/>
    <Setter Property="HorizontalOptions" Value="Start"/>
    <Setter Property="VerticalOptions" Value="Center"/>
    <Setter Property="BackgroundColor" Value="Transparent"/>
    <Setter Property="WidthRequest" Value="200"/>
    <Setter Property="Grid.Column" Value="1"/>
    <Setter Property="Grid.Row" Value="0"/>
    <Setter Property="local:KeyboardStyle.KeyboardFlags"
                    Value="Suggestions,CapitalizeCharacter"/>
    <Setter Property="behave:EntryHighlightBehavior">  <<===== How do I do this?????

    </Setter>
</Style>
1

There are 1 best solutions below

1
On BEST ANSWER

You may refer to this Consume a .NET MAUI behavior with a style, which points out the right way to put a Behavior property into a Style.

For your case, you may take up the following steps,

1.Adding an attached property in your EntryHighlightBehavior. Creating a static getter and setter for it and implementing logic in the propertyChanged delegate.

public class EntryHighlightBehavior : Behavior<Entry>
{
     public static readonly BindableProperty AttachBehaviorProperty =
BindableProperty.CreateAttached("AttachBehavior", typeof(bool), typeof(EntryHighlightBehavior), false, propertyChanged: OnAttachBehaviorChanged);

    public static bool GetAttachBehavior(BindableObject view)
    {
        return (bool)view.GetValue(AttachBehaviorProperty);
    }

    public static void SetAttachBehavior(BindableObject view, bool value)
    {
        view.SetValue(AttachBehaviorProperty, value);
    }

    static void OnAttachBehaviorChanged(BindableObject view, object oldValue, object newValue)
    {
        Entry entry = view as Entry;
        if (entry == null)
        {
            return;
        }

        bool attachBehavior = (bool)newValue;
        if (attachBehavior)
        {
            entry.Behaviors.Add(new EntryHighlightBehavior());
        }
        else
        {
            Behavior toRemove = entry.Behaviors.FirstOrDefault(b => b is EntryHighlightBehavior);
            if (toRemove != null)
            {
                entry.Behaviors.Remove(toRemove);
            }
        }
    }

    // the following code is the same as yours
    protected override void OnAttachedTo(Entry entry)
    {
      ...
    }

    protected override void OnDetachingFrom(Entry entry)
    {
    ...
    }

    void OnEntryFocusChanged(object sender, FocusEventArgs e)
    {
         ...
    }
}

2.Consuming the Behavior it in Style,

<Style x:Key="EntryPlain" TargetType="Entry">
    ...
    <Style.Setters>
        <Setter Property="local:EntryHighlightBehavior.AttachBehavior" Value="true" />
    </Style.Setters>

</Style>

Then you don't have to enumerate the Behavior property each time you create a new Entry.

If you still have any questions, feel to ask me.

Hope it helps!