Anthony Smyth
Anthony Smyth

Reputation: 305

How do I change the button style for disabled WPF buttons?

I'm working on making a simple tic-tac-toe game to familiarize myself with WPF, due to the amount of time it's been since I've used the format. I've been trying to disable the button, to prevent people from choosing the same square, after the content has been set to X or O. Here is a sample of my XAML code for the buttons:

        <Button Name="btmRight" Margin="10 10 10 10" Grid.Column="2" Grid.Row="2" FontSize="128">
            <Button.Style>
                <Style TargetType="Button">
                    <Style.Triggers>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Opacity" Value="1"/>
                            <Setter Property="Foreground" Value="Black"/>
                            <Setter Property="Background" Value="LightGray"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>

The buttons are enabled by default. I then use some simple C# code to disable the button, and set the content to X or O depending on the turn. However, despite the style trigger being in each button, the format is never changed. Something I might explore is putting a conditional in the code, to not change anything with the buttons if they have content, rather than disabling the button when it's clicked. Here is a sample of what I'm using for the C#:

mid.Click += (sender, e) =>
        {
            mid.Content = mark;
            TurnSwap();
            mid.IsEnabled = false;
            IsComplete();
        };

"mark" is a String that is set depending on the turn. The content is set to the mark value, which then rotates immediately after the content is set. The button is then disabled, and the game checks to see if someone has won yet. If I were to go with the option of manually disabling the button, I would surround that C# code in a conditional, to check if the content = "", which it is by default. I feel this option is a bit lazy, and I would like to learn the WPF solution for the concepts alone.

Upvotes: 1

Views: 5793

Answers (1)

Gaurang Dave
Gaurang Dave

Reputation: 4046

The following code is just a sample based on your question. I does not have tic-tac-toe game logic implemented. It demonstraits how to implement common style to button and also implmentation of common ClickEvent. You can use it and change it as per you need.

XAML

<Window x:Class="WPFTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFTest"
        mc:Ignorable="d"
        Title="TestWPF" Height="300" Width="400" 
        WindowStyle="None" WindowStartupLocation="CenterScreen">

    <Window.Resources>
        <Style x:Key="buttonStyle" TargetType="Button">

        <Setter Property="OverridesDefaultStyle" Value="True" />
        <Setter Property="Background" Value="MediumAquamarine" />
        <Setter Property="Foreground" Value="MediumBlue" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid Background="{TemplateBinding Background}">
                        <ContentPresenter x:Name="MyContentPresenter" 
                                      Content="{TemplateBinding Content}"
                                      HorizontalAlignment="Center" 
                                      VerticalAlignment="Center" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

        <Style.Triggers>
            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="Opacity" Value="1"/>
                <Setter Property="Foreground" Value="Black"/>
                <Setter Property="Background" Value="LightGray"/>
            </Trigger>
        </Style.Triggers>
    </Style>
    </Window.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <Button x:Name="btn1" Grid.Row="0" Grid.Column="0" Style="{StaticResource buttonStyle}" Click="btn_Click"/>
        <Button x:Name="btn2" Grid.Row="0" Grid.Column="1" Style="{StaticResource buttonStyle}" Click="btn_Click"/>
        <Button x:Name="btn3" Grid.Row="0" Grid.Column="2" Style="{StaticResource buttonStyle}" Click="btn_Click"/>

        <Button x:Name="btn4" Grid.Row="1" Grid.Column="0" Style="{StaticResource buttonStyle}" Click="btn_Click"/>
        <Button x:Name="btn5" Grid.Row="1" Grid.Column="1" Style="{StaticResource buttonStyle}" Click="btn_Click"/>
        <Button x:Name="btn6" Grid.Row="1" Grid.Column="2" Style="{StaticResource buttonStyle}" Click="btn_Click"/>

        <Button x:Name="btn7" Grid.Row="2" Grid.Column="0" Style="{StaticResource buttonStyle}" Click="btn_Click"/>
        <Button x:Name="btn8" Grid.Row="2" Grid.Column="1" Style="{StaticResource buttonStyle}" Click="btn_Click"/>
        <Button x:Name="btn9" Grid.Row="2" Grid.Column="2" Style="{StaticResource buttonStyle}" Click="btn_Click"/>

    </Grid>
</Window>

CS

using System;
using System.Windows;
using System.Windows.Controls;

namespace WPFTest
{
    public partial class MainWindow : Window
    {
        string sign = "X";
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btn_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Button currentButton = sender as Button;
                currentButton.Content = sign;
                currentButton.IsEnabled = false;

                swapSign();
            }
            catch (Exception ex)
            {
            }
        }

        private void swapSign()
        {
            if (sign == "X")
                sign = "O";
            else
                sign = "X";
        }
    }
}

UPDATE-1 I changed the style in XAML. Check above. One thing to note here is that you have to set Background and Foreground properties of Button Style like I set.

Upvotes: 2

Related Questions