1

I'm using ObservableProperty attribute from MVVM toolkit, for the string SearchString which has binding for the TextBlock.Text property. I want to start command once change in TextBlock was made so I have set the attribute for change notification.

ViewModel part:

    [ObservableProperty]
    [NotifyCanExecuteChangedFor(nameof(UpdateSearchCommand))]
    string searchString = string.Empty;

    [RelayCommand]
    async Task UpdateSearch()
    {
        MessageBox.Show("Hello");
        await Task.CompletedTask;
    }

View part:

       <TextBox x:Name="txtSearch" Width="200" Height="30"
          Grid.Row="0" Grid.Column="0"
          HorizontalAlignment="Right"
          VerticalAlignment="Center"
             BorderThickness="0"
             Margin="0 0 10 0"
             Padding="0 5 0 0"
             Text="{Binding SearchString}">
       <TextBox.ToolTip>
          <ToolTip Content="{Binding Loc[SearchNameOrDesc_TT]}"/>
       </TextBox.ToolTip>

I don't know why, but when I write something into textBlock, the command does not trigger.

Does anybody has some experience with such as behavior?

I'll be glad for any advice or even a hint.

Thanks

JMan
  • 60
  • 7
  • 2
    I think you've misunderstood what canexecutechanged does. It forces a check on whether a command should be disabled or not. It does not run the command. – Andy Oct 13 '22 at 19:44
  • If you had a full on property for SearchString you could call a method from the setter. If you built the command in code rather than automatic attribute based creation then you could use that method in a command. – Andy Oct 13 '22 at 19:47
  • @Andy you still can do that, see my answer below. There is a pattern for it with partial methods and the convention to use On**PropertyName**Changed() – Julian Oct 13 '22 at 19:52

1 Answers1

1

You didn't bind your Command to your View. First of all, you need to understand how the binding works.

You didn't bind your Command to anything. Instead, you're only notifying the View to update any bindings to the Command, which is not doing anything here, because it's not bound to anything.

If you want to invoke the Command through the binding of the SearchString property, you'll need to update your code as follows:

[ObservableProperty]
string searchString;

partial void OnSearchStringChanged(string value)
{
    UpdateSearchCommand.Execute(null); //or pass value, if you need to 
}

[RelayCommand]
void UpdateSearch()
{
    MessageBox.Show("Hello");
}

Note: This is not an ideal implementation, just a way to fix your code based on how I understood it.

You should probably familiarize yourself more with property bindings and commands before using advanced things like MVVM Code Generators.

Julian
  • 5,290
  • 1
  • 17
  • 40
  • Thanks for the explanation. I obviously misunderstood the functionality of the [NotifyCanExecuteChangeFor] attribute. I'm new to WPF and MVVM patern overall and don't fully understand it yet. For example, it's not yet completely clear to me how to invoke events in the correct way while maintaining the use of the ViewModel. From WinForms I'm used to just manage events in the code behind of the UI component. What is the correct way using the MVVM pattern or maybe even the MVVM community toolkit? Let's say I want to use the TextChanged event .... Thank you again – JMan Oct 14 '22 at 05:01
  • `partial void OnSearchStringChanged(string value)` is the equivalent of handling the `TextChanged` event in the MVVM community toolkit. – mm8 Oct 14 '22 at 12:54