0

I have following ICommand assignment in MainViewModel:

MineCommand = new ActionCommand(
    c => MineRulesForPolygon(SelectedPolygon, "stringParameter"),
    c => SelectedPolygon != null && !SelectedPolygon.IsLoading 
        && SelectedPolygon.Records != null
        && MinSupport > 0 && MinSupport <= 1
        && MinConfidence > 0 && MinConfidence <= 1
        && !IsMining);

First argument is Execute and the second is CanExecute method. SelectedPolygon.IsLoading is true until the data is loaded (SelectedPolygon is another ViewModel, which gets selected from a collection of those models):

public void LoadData(string latColumn = "latitude", string lonColumn = "longitude", Action postLoading = null) 
{
    if (_context != null)
    {
        new Thread(() =>
        {
            IsLoading = true;
            if (_context.SelectWithinPolygon(SqlPolygon, latColumn, lonColumn, out DataTable tab))
            {
                Records = tab;
            }
            IsLoading = false;
            Application.Current.Dispatcher.Invoke(DispatcherPriority.ApplicationIdle,
                new Action(() => { postLoading?.Invoke(); }));
        })
        {
            Name = "Polygon Data Loading Thread"
        }.Start();
    }
}

You can see me trying almost this solution (is mixed with second answer from this question). The way of calling LoadData from MainViewModel is:

SelectedPolygon.LoadData(postLoading: () => MineCommand.RaiseCanExecuteChanged());

having RaiseCanExecuteChanged() as follows:

public void RaiseCanExecuteChanged()
{
    CommandManager.InvalidateRequerySuggested();
}

To ensure the condition of CanExecute is true, I placed the breakpoint at lambda () => MineCommand.RaiseCanExecuteChanged() directly in parameters, and evaluated those values from CanExecute; as expected, evaluation results true. However the button bound to this command remains disabled:

        <Button Grid.Row="5"
                HorizontalAlignment="Center"
                Content="Mine"
                Style="{StaticResource CommandButtonStyle}"
                Command="{Binding MineCommand}" >
        </Button>

How can I force it to update its IsEnabled property according to CanExecute change?

Arli Chokoev
  • 521
  • 6
  • 22
  • How are you verifying that the breakpoint at lambda `() => MinCommand.RaiseCanExecuteChanged()` evalutes to true? That is not a conditional lamdba expression. Have you tried instead to directly put the breakpoint on `c => SelectedPolygon != null && ...`? Perhaps one of those conditionals is returning false. – Tam Bui Nov 19 '20 at 17:20
  • I don't try to verify. whether this lambda is true, because this method is `void`. I only evaluate those values, when this lambda is about to execute. By the way, the `c => SelectedPolygon != null && ...` is not getting called. – Arli Chokoev Nov 19 '20 at 17:37
  • I was merely repeating what you said in your original post, that you "placed the breakpoint on lambda `() => MineCommand.RaiseCanExecuteChanged()`; as expected, evaluation results true". How (and what) were you evaluating for the results to be true? If you are now saying that `c => SelectedPolygon != null && ...` is not getting called at all, then you've touched on the reason why your button is still disabled. – Tam Bui Nov 19 '20 at 18:17
  • 1. Place the breakpoint to lambda 2. Stop at this point 3. Select the whole `CanExecute` condition 4. Press Ctrl+D, Q Sure, reason is that WPF does not react on `CanExecute` change -> getter is not called, and the way to solve it is literally my question. – Arli Chokoev Nov 19 '20 at 21:16

0 Answers0