0

I have a button which is:

<Button Style="{StaticResource ButtonStylePermit1}" 
 Click="permit1_Click" x:Name="permit1" IsEnabled="False"/>

and in my .cs code I also have a int floor = 1;

I want to be able to enable the button if the floor = 2 and disable the button if not. What is the best possible way to do this?

3
  • You can use an if/else statement, or permit1.IsEnabled = (floor == 2);. Commented Mar 18, 2019 at 1:05
  • see also e.g. stackoverflow.com/questions/3849265/… Commented Mar 18, 2019 at 3:59
  • Maybe you can update the question to show the button xaml (so to check the binding), the datacontext setup and the Floor property to see the INotifyPropertyChange implementation. That will help identifying why the code is not working Commented Mar 19, 2019 at 1:03

3 Answers 3

0

in your .cs code, create a method that either disables or enables the button, then call that method whenever floor changes value. So a simple way to achieve that is to create a Public Property on floor member, and use the property to change the value of floor as well as to change the enabled property of you button.

private int floor;

public int Floor{
    get { return this.floor;}
    set { 
        this.floor = value; 
        if (this.floor == 2)
        { this.permit1.Enabled = false }
        else {this.permit1.Enabled = true}     
    }
}
this.Floor = 1;
Sign up to request clarification or add additional context in comments.

2 Comments

Is there another way to do this? Because I have many buttons like this one for different floors?
Sure there are different ways of doing this. But in the end if buttons are suppose to enable/disable independent of each different floor, then you stille need to create that logical link between floor Property and the related button. Do you have more code snippets of the view and code behind? then it would be easier understand what you are working with here.
0


Two solution are provided as follows:

  1. Straight Forward idea:

    if (floor == 2) permit1.IsEnabled = true;
    else permit1.IsEnabled = false;

  2. Ternary

    permit1.IsEnabled = (floor==2) ? true : false;

You can try the following XAML code as an example:

<WrapPanel>
    <Button x:Name="permit1" Content="Test" Width="200" Click="permit1_Click" IsEnabled="False" Background="Red"/>
    <Button x:Name="Button1" Content="Press here" Width="100" Click="Button_Click"/>
</WrapPanel>

And the MainWindow.xaml.cs includes the following C# code:

int floor;
    Random random01 = new Random();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void permit1_Click(object sender, RoutedEventArgs e)
    {
         //your code here
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        floor = (int)Math.Round(random01.NextDouble(), 0) + 1;
        Button1.Content = floor;
        permit1.IsEnabled = (floor==2) ? true : false;
        /*
        if (floor == 2)
            permit1.IsEnabled = true;
        else
            permit1.IsEnabled = false;
        */
    }

2 Comments

Why do you use permit1.IsEnabled = (floor==2) ? true : false; ? You can use simple permit1.IsEnabled = floor==2;.
@Arci, YES! You are correct. I just want to give an example of Ternary for Cutie.
0

In WPF typical way for handling this would be to use data binding with value convertor

Here is a quick look at the changes you will need to do:

In your xaml you will bind your control's IsEnabled property to Floor

<Button  Content="Click Me!" Click="button_Click" 
x:Name="permit1" IsEnabled="{Binding Floor, Converter={StaticResource  converter}}">

Floor is an int, while IsEnabled is the bool, to link these you need the converter, I have put in the converter as a windows resources so that it can be used for multiple different objects (in the same class, but you can put it in a central resource.xaml file).

<Window.Resources>
    <local:FloorToEnableConverter x:Key="converter" />
</Window.Resources>

For the framework to be able to find your property Floor it should be in the datacontext of the XAML, I have done this in the code behind constructor

public MainWindow()
{
    InitializeComponent();
    this.DataContext = this;
}

You will need to define the logic for this converter in your own class, which is just the implementation of IValueConverter interface

 public class FloorToEnableConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if (value == null)
                    throw new ArgumentException("value cannot be null");

                if ((int)value == 1)
                    return false;
                if ((int)value == 2)
                    return true;

                // for all other values disable
                return false;
            }

            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
}

Finally when the property changes you will need to notify the UI about the changes, so this needs to be implemented by INotifyPropertyChangeInterface

I have implemented this on my demo class

public partial class MainWindow : Window, INotifyPropertyChanged

And the actual code is:

public event PropertyChangedEventHandler PropertyChanged;

        public int floor;
        public int Floor
        {
            get { return this.floor;}
            set { this.floor = value;
                // The string here should exactly match the property name
                OnPropertyChanged("Floor"); }
        }
        private void OnPropertyChanged(string property)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(property));
        }

This should work, also even though in this example I have implemented the code for change notification in the code behind class, in WPF try to avoid using the code behind class, that was a required in win forms, but WPF provides alternate mechanism for this. Have a look at the MVVM pattern for a better way to structure the code.

7 Comments

Would this also work for other buttons for example if the floor = 1, will it enable it?
Yes, it will work for each button with respect to the floor property you bound it to. The converter class is shared, so if you want the conversion logic to be different for each floor then you might need to create more convertors.
Once you have setup the INotifyPropertyChange and created a convertor, you just need to setup the binding properly in the xaml for this to work for various buttons
I tried implementing this code but the button is still enabled when I change floors.
switch (((ListViewItem)((ListView)sender).SelectedItem).Name) { case "Ground": imageMap.Source = new BitmapImage(new Uri(@"\main\1.png", UriKind.Relative)); floor = 1; break; case "Second": floor = 2; imageMap.Source = new BitmapImage(new Uri(@"\main\2.png", UriKind.Relative)); break;
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.