C# WPF CanExecuteChanged

66 Views Asked by At

I have created a CustomControl which extends TextBox. Within my control I have added a button:

AppTextBox.cs

public static readonly DependencyProperty ButtonCommandProperty =
        DependencyProperty.Register(nameof(ButtonCommand), typeof(ICommand), typeof(AppTextBox),
            new PropertyMetadata(null, OnButtonCommandChanged));

    public ICommand ButtonCommand
    {
        get => (ICommand)GetValue(ButtonCommandProperty);
        set => SetValue(ButtonCommandProperty, value);
    }

private static void OnButtonCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is AppTextBox atb)
        {
            atb.ButtonCommand = (ICommand)e.NewValue;
            atb.SetButtonIsActive(atb);
        }
    }

This is how I setup the TextBox:

<ctrl:AppTextBox ButtonCommand="{Binding AddSpokenFormCommand}"
                 ButtonLabel="+"
                 Label="Spoken Form"
                 Text="{Binding SpokenFormText, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
                 x:Name="txtSpokenForm" />

Within my ViewModel I have the following:

public RelayCommand AddSpokenFormCommand { get; }

AddSpokenFormCommand = new(OnAddSpokenFormCommand, AddSpokenFormCommandCanExecute);

private bool AddSpokenFormCommandCanExecute() => SpokenFormText.Length != 0;

The issue I am facing is that the CustomControl is not always set to the correct state.

I have a listbox where I can select an entry, when the entry loads the CustomControl seems to keep the state it was in from the last record.

CustomControl when first loaded: (This is in the correct state) Initial

CustomControl when text added: (This is in the correct state) With Text

CustomControl when moved to next record: (as you can see there is no text, but the button is active (and it shouldnt be)) Next Record

How can I force the UI to refresh based on the data that it now holds after reloading?

1

There are 1 best solutions below

0
On BEST ANSWER

Setup in AppTextBox.cs was causing the issues.

Because the class has instance methods, there is no need to pass around a reference.

Once I removed all of the atb.x then the control behaved as it should do.

Thanks to Clemens for the pointers