-1

I am trying to figure out how I can set the "IsEnabled" property to false on a Button but then have the children (in my case a Combobox) be enabled. It seems the children inherit the property value from the parent element (in this case the disabled button) and therefore also disables itself. How can I prevent this?

I have tried to lookup answers but they all use "Override Metadata" which WinUI3 and Windows App SDK do not contain.

<Button
    x:Name="Button1"
    IsEnabled="False">
    <Button.Content>
        <ComboBox x:Name="ComboBox1" />
    </Button.Content>
</Button>
Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21
  • Can you share some code about your ``Button`` and ``ComboBox``? It'd be easier to help. – Andrew KeepCoding Oct 24 '22 at 12:11
  • So, as you can see, the parent (Button1) is disabled, but I want to enable the child inside of the button (ComboBox1). As far as I know, children inherit their parent's properties, which in this case is the IsEnabled property which is set to false. How can override this so that ComboBox1 is enabled? – Elijah Wasson Oct 24 '22 at 15:57

1 Answers1

0

You can create a custom control like this:

Generic.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:Buttons">

    <Style TargetType="local:CustomButton">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:CustomButton">
                    <Grid
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                        <Button
                            x:Name="ButtonControl"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center"
                            IsEnabled="{TemplateBinding IsButtonEnabled}" />
                        <ContentControl
                            x:Name="ContentControl"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center"
                            Content="{TemplateBinding Content}"
                            IsEnabled="{TemplateBinding IsContentEnabled}" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

CustomButton.cs

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

namespace Buttons;

[TemplatePart(Name = nameof(ButtonControl), Type = typeof(Button))]
[TemplatePart(Name = nameof(ContentControl), Type = typeof(ContentControl))]
public sealed class CustomButton : ContentControl
{
    public static readonly DependencyProperty IsButtonEnabledProperty = DependencyProperty.Register(
        nameof(IsButtonEnabled),
        typeof(bool),
        typeof(CustomButton),
        new PropertyMetadata(true));

    public static readonly DependencyProperty IsContentEnabledProperty = DependencyProperty.Register(
        nameof(IsContentEnabled),
        typeof(bool),
        typeof(CustomButton),
        new PropertyMetadata(true));

    public CustomButton()
    {
        this.DefaultStyleKey = typeof(CustomButton);
    }

    public bool IsButtonEnabled
    {
        get => (bool)GetValue(IsButtonEnabledProperty);
        set => SetValue(IsButtonEnabledProperty, value);
    }

    public bool IsContentEnabled
    {
        get => (bool)GetValue(IsContentEnabledProperty);
        set => SetValue(IsContentEnabledProperty, value);
    }

    private Button? ButtonControl { get; set; }

    private ContentControl? ContentControl { get; set; }

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        ButtonControl = GetTemplateChild(nameof(ButtonControl)) as Button;

        if (GetTemplateChild(nameof(ContentControl)) is ContentControl contentControl)
        {
            if (ContentControl is not null)
            {
                ContentControl.SizeChanged -= ContentControl_SizeChanged;
            }

            ContentControl = contentControl;
            ContentControl.SizeChanged += ContentControl_SizeChanged;
        }
    }

    private void ContentControl_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        if (sender is ContentControl contentControl &&
            ButtonControl is not null)
        {
            ButtonControl.Width = contentControl.ActualWidth + 20.0;
            ButtonControl.Height = contentControl.ActualHeight + 20.0;
        }
    }
}

And use it like this:

MainWindow.xaml

<Grid>
    <local:CustomButton
        IsButtonEnabled="False"
        IsContentEnabled="True">
        <ComboBox
            SelectedIndex="0"
            SelectionChanged="ComboBox_SelectionChanged">
            <x:String>Blue</x:String>
            <x:String>Green</x:String>
            <x:String>Red</x:String>
        </ComboBox>
    </local:CustomButton>
</Grid>
Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21