Problem with custom control

2

I created a custom search bar with an entry. I need to get the text of this entry to be a search parameter.

So I created a custom property that uses the Text property of entry. But this custom property does not take the text from the custom search bar.

What am I doing wrong? Below is the code for the custom control.

Code of the search button click event of the search bar customized.

    private async void SbcPesquisar_OnClicked(object sender, EventArgs e)
        {            
            string busca = SbcPesquisar.TextSearch;
            List<Promocao> Promocoes = await PromocaoService.GetListaPromocoes(busca);
            LstPromocoes.ItemsSource = Promocoes;
        }

Control Bihind Code

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace MeDeiBem.Controls
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class SearchBarCustom : ContentView
    {
        public event EventHandler ClickScope;
        public SearchBarCustom ()
        {
            InitializeComponent ();
        }
        public static readonly BindableProperty TextSearchProperty = 
            BindableProperty.Create(
                propertyName: "TextSearch",
                returnType: typeof(string),
                declaringType: typeof(SearchBarCustom),
                defaultValue: "",
                defaultBindingMode: BindingMode.TwoWay,
                propertyChanged: TextSearchPropertyChanged
            );

        public string TextSearch
        {
            get { return (string)GetValue(TextSearchProperty); }
            set { SetValue(TextSearchProperty, value); }
        }
        private static void TextSearchPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var searchBarCustom = (SearchBarCustom)bindable;
            searchBarCustom.textSearch.Text = (string)newValue;
        }
        private void On_clickScope(object sender, EventArgs e)
        {
            if (ClickScope != null)
            {
                ClickScope(sender, e);
            }
        }
    }
}

XAML Code:

    <?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MeDeiBem.FontsAwesome;assembly=MeDeiBem"
             x:Class="MeDeiBem.Controls.SearchBarCustom">
  <ContentView.Content>
        <Frame Margin="10, 0, 10, 0" Padding="2" BorderColor="#49c1ff" CornerRadius="5" BackgroundColor="Transparent" HeightRequest="60">
            <StackLayout Orientation="Horizontal" BackgroundColor="Transparent">
                <Entry x:Name="textSearch"
                       Placeholder="Digite o que procura"                       
                       PlaceholderColor="Black"
                       FontSize="Medium"                       
                       BackgroundColor="Transparent"
                       HorizontalOptions="FillAndExpand" 
                       />

                <Button Text="{x:Static local:Fontes.FASearch}" 
                        FontSize="30"                          
                        BorderWidth="0"
                        BackgroundColor="Transparent"
                        WidthRequest="60" 
                        HorizontalOptions="End" 
                        Clicked="On_clickScope" />
            </StackLayout>
        </Frame>
  </ContentView.Content>
</ContentView>

XAML code where I'm using the component:

<controls:SearchBarCustom x:Name="SbcPesquisar" ClickScope="SbcPesquisar_OnClicked" />
    
asked by anonymous 11.06.2018 / 15:34

1 answer

2

What was missing was that you used the BindableProperty TextSearchProperty you created in your component. She is already exposed to Bindings.

Then you should have a property in your ViewModel , like SearchText , for example, and use it with the binding on the component. So:

<controls:SearchBarCustom x:Name="SbcPesquisar" 
                          TextSearch="{Binding SearchText}"
                          ClickScope="SbcPesquisar_OnClicked" />

This is because on your% delegate% set to propertyChanged you have to reflect the BindableProperty property change on the% internal TextSearch lete component, but when the change occurs in Entry its Entry property is not being 'notified'.

Edit:

Without using TextSearch (as is the case with MVVM), exposing the property as bindable ends up becoming unnecessary because it is precisely what it was designed for. But with a few small adjustments you can solve the problem you are facing.

You will need to add a Bindings property to your component, set it to be its own x:Name , and bind the text of your BindingContext to the property you exposed in the component's codebehind. So:

<?xml version="1.0" encoding="UTF-8"?>
<ContentView ...
             x:Class="MeDeiBem.Controls.SearchBarCustom"
             x:Name="searchBarCustom">
    <ContentView.Content>
        <Frame Margin="10, 0, 10, 0" 
               BindingContext="{Reference searchBarCustom}"
               ...>
            <StackLayout Orientation="Horizontal" 
                         BackgroundColor="Transparent">
                <Entry x:Name="textSearch"
                       Text="{Binding TextSearch}"
                       Placeholder="Digite o que procura"                       
                       .../>

                <Button ... />
            </StackLayout>
        </Frame>
  </ContentView.Content>
</ContentView>

* Where is the "..." is for you to keep your code the way you are currently

This small setting will cause changes in Entry to reflect on the Entry and property vice versa . You can now remove the implementation of TextSearch you used in propertyChanged: TextSearchPropertyChanged .

By doing so you will be able to retrieve the contents of the property as you were trying:

private async void SbcPesquisar_OnClicked(object sender, EventArgs e)
{            
    string busca = SbcPesquisar.TextSearch;
    List<Promocao> Promocoes = await PromocaoService.GetListaPromocoes(busca);
    LstPromocoes.ItemsSource = Promocoes;
}

I hope this helps.

    
11.06.2018 / 16:46