Caboose
Caboose

Reputation: 463

XAML IsEnabled Binding not working as expected

I've very recently had to jump into a new project using WPF/XAML. While I have plenty of experience in C# and ASP.Net MVC, this transition hasn't gone as smoothly for me as I would've hoped (yet).

The problem:

I need to bind a button to a checkbox. I.e. I need to bind the IsEnabled property of the Button to the IsChecked property of the CheckBox. I can't seem to get this to work in a straight forward way, and weirdly enough it seems to start working as I want if I used Snoop to disable the button, but only if i do that.

To be clear, both the checkbox and button work independently as intended. Just the binding disabling the Button when the Checkbox is clicked is doing nothing.

This is roughly the XAML I have currently:

<Button Grid.Column="1" Grid.Row="1" Content="get curve" 
     IsEnabled="{Binding ElementName=IsStraightCheckBox, Path=IsChecked, Mode=TwoWay}"
     Command="{Binding CustomCommand}"  
     Style="{DynamicResource ButtonFormStyle}" />
<CheckBox Name="IsStraightCheckBox" IsChecked="{Binding DataObject.Alignment, Converter={StaticResource CustomConverter}, Mode=TwoWay}"/>

The binding/converter on the CheckBox is working how I want it to, but I don't know if it's interfering with the other end of what I'm trying to accomplish.

I'm not sure if I've done something wrong structurally here or if I'm simply misunderstanding how bindings work.

EDIT: The answer provided below is generally the correct way to do what I wanted to accomplish. My code base has unrelated issues causing bindings to fail, thus my confusion.

Upvotes: 0

Views: 2893

Answers (1)

aybe
aybe

Reputation: 16672

Here's some simple code that:

  • has a button whose state is controlled by the check box
  • the check box itself is driven by a toggle button with a trivial converter

XAML:

<Window
    x:Class="WpfApp1.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:local="clr-namespace:WpfApp1"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Grid>
        <StackPanel>
            <StackPanel.Resources>
                <local:MyConverter x:Key="Converter" />
            </StackPanel.Resources>
            <Button Content="Click me" IsEnabled="{Binding ElementName=Box, Path=IsChecked}" />
            <CheckBox
                x:Name="Box"
                Content="Enable the button"
                IsEnabled="{Binding ElementName=Toggle, Path=IsChecked, Converter={StaticResource Converter}}" />
            <ToggleButton x:Name="Toggle" Content="Lock the checkbox" />
        </StackPanel>
    </Grid>
</Window>

Converter:

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace WpfApp1
{
    internal class MyConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value is bool b ? b : DependencyProperty.UnsetValue;
        }

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

Few notes

  • do not always trust VS XAML Designer, in this case the button does not react when enabling check box through XAML; in Blend however, you can see it changing
  • check potential binding errors in Output window, note that it is normal some bindings will error at the start of an (large) application because these are evaluated quite early, you'll be interested in their value when you are using the application

Upvotes: 1

Related Questions