Tk1993
Tk1993

Reputation: 521

WPF:change background color of dynamically created buttons on a single click event

I've created a button on a click event:

  private void  btnAddNewQuestion_Click(object sender, RoutedEventArgs e)
        {
         Button btnQuestion = new Button();
         btnQuestion.Name="btn"+counter.toString();
         btnQuestion.Content="Enter/Edit your question here";
         btnQuestion.Background=Brushes.Grey;
         btnQuestion.Click += new RoutedEventHandler(btnEnterQuestion_Click);   
         counter++;
        }

And here's the click event of dynamically created button:

   private void  btnEnterQuestion_Click(object sender, RoutedEventArgs e)
        {
                        Button button = sender as Button;
                        button.Background=Brushes.White;
        }

PROBLEM:

I want that on button click only the clicked button's background should change to White, and the previously clicked button should change its color back to to Grey

For reference I'm attaching a screenshot:

On click of first button

On click of second button

UPDATE

I'm adding the XAML code for btnAddNewQuestion

<Button x:Name="btnAddNewQuestion" Click="btnAddNewQuestion_Click" />

Upvotes: 1

Views: 5811

Answers (3)

grek40
grek40

Reputation: 13438

I want to present you a more XAML focused approach, where the buttons are managed as RadioButton in the view and as a QuestionButtonViewModel in the code behind. The change of colors is managed by ControlTemplate.Triggers based on the IsChecked property.

XAML:

<Grid x:Name="grid1">
    <Grid.Resources>
        <ControlTemplate x:Key="QuestionButtonControlTemplate" TargetType="{x:Type RadioButton}">
            <Border x:Name="buttonBorder" BorderBrush="DarkGray" Background="WhiteSmoke" BorderThickness="1" Padding="5">
                <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Left"/>
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="IsChecked" Value="True">
                    <Setter TargetName="buttonBorder" Property="BorderBrush" Value="Goldenrod"/>
                    <Setter TargetName="buttonBorder" Property="Background" Value="White"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Grid.Resources>

    <StackPanel Width="300" Margin="5">
        <ItemsControl ItemsSource="{Binding QuestionButtons}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <RadioButton
                        Content="{Binding QuestionText}"
                        Click="RadioButton_Click"
                        Margin="3"
                        GroupName="QuestionButtons"
                        Template="{StaticResource QuestionButtonControlTemplate}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

        <Button Content="Add new Question" Click="AddQuestion_Click" Margin="3"/>
    </StackPanel>
</Grid>

Code Behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        QuestionButtons = new ObservableCollection<QuestionButtonViewModel>();

        Loaded += MainWindow_Loaded;
    }

    public ObservableCollection<QuestionButtonViewModel> QuestionButtons { get; set; }

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        grid1.DataContext = this;
    }

    private void AddQuestion_Click(object sender, RoutedEventArgs e)
    {
        QuestionButtons.Add(new QuestionButtonViewModel() { QuestionText = "Enter/Edit your question here" });
    }

    private void RadioButton_Click(object sender, RoutedEventArgs e)
    {
        // whatever you want to do, other than setting visual things
    }

}

public abstract class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChangedEvent([CallerMemberName]string prop = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(prop));
    }
}

public class QuestionButtonViewModel : BaseViewModel
{
    private string _QuestionText;
    public string QuestionText
    {
        get { return _QuestionText; }
        set
        {
            if (_QuestionText != value)
            {
                _QuestionText = value;
                RaisePropertyChangedEvent();
            }
        }
    }
}

Upvotes: 0

Moslem Shahsavan
Moslem Shahsavan

Reputation: 1337

Search in spMain.Children and changed all button background and next changed current background button has clicked.

 private void btnEnterQuestion_Click(object sender, RoutedEventArgs e)
    {
        foreach (var btn in spMain.Children.OfType<Button>().Where(x=> x.Name.StartsWith("btn")))
            btn.Background =  Brushes.Gray;

        Button button = sender as Button;
        button.Background = Brushes.White;
    }

Upvotes: 4

JohnChris
JohnChris

Reputation: 1360

Here is the code I got to make it work, just made a new project and tried with 1 button made on design view, then programmatically creating another button and setting it in the stackpanel. When clicking the second button, in the click event you call the first button by name and change its background... hope that's what you needed.

CODE BEHIND

int counter = 0;
    private void btnAddNewQuestion_Click(object sender, RoutedEventArgs e)
    {
        Button btnQuestion = new Button();
        btnQuestion.Name = "btn" + counter.ToString();
        spMain.Children.Add(btnQuestion);
        btnQuestion.Content = "Enter/Edit your question here";
        btnQuestion.Background = Brushes.Gray;
        btnQuestion.Click += new RoutedEventHandler(btnEnterQuestion_Click);
        counter++;
    }

    private void btnEnterQuestion_Click(object sender, RoutedEventArgs e)
    {
        Button button = sender as Button;
        button.Background = Brushes.White;
        button1.Background = Brushes.Gray; // change of first buttons color
    }

XAML

 <Grid>
    <StackPanel x:Name="spMain">
        <Button x:Name="button1" Content="Button" Click="btnAddNewQuestion_Click"/>
    </StackPanel>
</Grid>

Upvotes: 0

Related Questions