1

I have a button style declared in Xaml, I did a Click Event in my C# file to, when clicked, change some style but now, when clicked again, I want to reset my styles to inicial style. How I can manage the clicks and reset the style?

<flv:FlowListView FlowColumnCount="3" SeparatorVisibility="None" HasUnevenRows="true"
                    FlowItemTappedCommand="{Binding ItemTappedCommand}" FlowLastTappedItem="{Binding LastTappedItem}"
                    FlowItemsSource="{Binding MyCategories}" >

    <flv:FlowListView.FlowColumnTemplate>
      <DataTemplate>
         <Button Text="{Binding Name}"
         TextColor="White"
         x:Name="categoryButtons"
         Clicked="ButtonSelected"
         ContentLayout="Top"
         BackgroundColor="Transparent"
         BorderColor="White"
         BorderWidth="2"
         CornerRadius="6"
         Margin="5,5,5,10" />
      </DataTemplate>
   </flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
public void ButtonSelected(object sender, EventArgs e)
        {
            var button = (Button)sender;
            button.BackgroundColor = Color.Blue;
        }
LOL Jovem
  • 197
  • 2
  • 17
  • please do not ask the same question multiple times – Jason Apr 30 '19 at 10:23
  • @Jason My previous question was already answered, I am now able to change the colour of the button uppon a click Event, what I'm trying to do now is whenever the button is clicked after being clicked previsously and changing colour accordingly I want to reset the style, like selecting and deselecting button as a visual representation for the user, do you understand what I'm saying? Thanks in advance! – LOL Jovem Apr 30 '19 at 10:30
  • Then you need to save the button state (whatever set of properties you want to modify) and restore it. – Jason Apr 30 '19 at 10:39
  • @Jason ok I can save the initial button state in a ResourceDictionary, but how I can restore it through my C# file? Can you show me some code? – LOL Jovem Apr 30 '19 at 10:43
  • @LOLJovem Have a try with custom a property of Button.If needed ,change style to the custome property value. – Junior Jiang May 01 '19 at 02:55

2 Answers2

0

Okay so your FlowItemsSource is Binded to your the ObservableCollection<Category> or whatever model object type you are using. The button in your DataTemplate is binded to the Name property of your Category class.

Assign a trigger to your Button as follows and then when the button is clicked, set the property in the model object to true/false depending on the current state.

<Button
    Text="{Binding Name}"
    TextColor="White"
    Command="{Binding ToggleCommand}"
    ContentLayout="Top"
    BackgroundColor="Transparent"
    BorderColor="White"
    BorderWidth="2"
    CornerRadius="6"
    Margin="5,5,5,10" >
    <Button.Triggers>
        <DataTrigger
            TargetType="Button"
            Binding="{Binding IsToggled}"
            Value="True">
            <Setter Property="BackgroundColor" Value="Blue" />
        </DataTrigger>
    </Button.Triggers>
</Button>

Also, as shown above, I would suggest putting an ICommand property in your Category class to execute the changing of the bool property.

The Command/Code for the Category model object would look like such:

//Constructor
public Category()
{
    ToggleCommand = new Command(() =>
    {
        IsToggled = !IsToggled;
        NotifyPropertyChanged(nameof(IsToggled));
    };
}

public ICommand ToggleCommand { get; }

public bool IsToggled { get; set; }

Then once your state is toggled to true the button will change to a blue color and then when it's false, it will go back to the original transparent.

Also, make sure your Category class is implementing INotifyPropertyChanged

TaylorD
  • 687
  • 3
  • 7
  • I've already implemented the code given but it isn't working now it doesn't even change the background colour to blue, I don't know if it is because I've changed NotifyPropertyChanged code. Take a look: ` public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = "") { var changed = PropertyChanged; if (changed == null) return; changed.Invoke(this, new PropertyChangedEventArgs(propertyName)); } ` – LOL Jovem Apr 30 '19 at 14:18
  • Im not being able to format the comment for code. Im sorry about that. – LOL Jovem Apr 30 '19 at 14:23
  • Is your class implementing the INotifyPropertyChanged interface? `public class Category: INotifyPropertyChanged` – TaylorD Apr 30 '19 at 14:36
  • I have a file with that OnPropertyChanged, BaseViewModel, and my Category class is like Category : BaseViewModel, so I can call OnPropertyChanged method. – LOL Jovem Apr 30 '19 at 15:06
  • Verify the `ToggleCommand` gets hit in the Category class by putting a breakpoint. Also, make sure there are no Binding errors showing up in the console output. – TaylorD Apr 30 '19 at 15:28
  • Ok, I will do some tests, but now I will stay some hours without the PC (Im at school and need to go to my house). Thanks a lot for your help. Maybe If you want to wait for my response maybe I will leave it here later. Sorry for any inconvinience. – LOL Jovem Apr 30 '19 at 15:43
  • I did some tests and what I saw is the c# code isnt being called. – LOL Jovem Apr 30 '19 at 21:39
  • Is the name for sure populated in the view? If so, next thing to look at is making sure the property names are the same in code and the **xaml**. Also, make sure that the command is set up in the constructor of the Category class. If not, then that should happen there. JUST to make sure, the Category class is the appropriate object in the `MyCategories` list correct? – TaylorD May 01 '19 at 13:04
0

So I did this to the style reset to default:

public partial class CategoriesMenuDetail : ContentPage
    {
        public Dictionary<int, Btn> buttons { get; set; }

        public CategoriesMenuDetail()
        {
            InitializeComponent();
            buttons = new Dictionary<int, Btn>();
        }

        public void ButtonSelected(object sender, EventArgs e)
        {          
            var button = (Button)sender;

            if (!buttons.ContainsKey(button.GetHashCode()))
            {
                buttons.Add(button.GetHashCode(), new Btn(button));
            }

            bool state = buttons[button.GetHashCode()].Toogle();

            var bgColor = (state) ? Color.FromHex("#26047AD5") : Color.FromHex("#40000000");
            var borderColor = (state) ? Color.FromHex("#FF8A00") : Color.FromHex("#FFFFFF");

            button.BackgroundColor = bgColor;
            button.BorderColor = borderColor;
        }
    }

    public  class Btn
    {
        private Button _button { get; set; }

        private bool isToogle = false;

        public Btn(Button button)
        {
            _button = button;
        }

        public bool Toogle()
        {
            isToogle = !isToogle;
            return isToogle;
        }
    }
LOL Jovem
  • 197
  • 2
  • 17