0

I have an application in MAUI.NET with MVVM architecture. In ViewModels I am setting PropertyChanged as most of examples through the web.

In my application the user opens lots of views (that are of type ContentView). Each time the ContentView is assigned to main area of application and drawn on the monitor, the setters of ViewModels are fired (when they have already binded value).

What I need is to limit this behaviour (firing setters in ViewModels) only to the moment when the user himself/herself click on the checkbox, omitting the moments when the framework just draw the checkbox which have binded value set to true.

In this situation call stack says that external code is firing this.

Anyone have any idea how to deal with this?

edit:

viewmodel:

internal class CheckboxViewModel : BaseViewModel
{
    public bool Value
    {
        get
        {
            ...
        }
        set 
        {
            //here I compute value and set status to be changed

            //this is fired when the user click on checkbox = ok
            //but also when checkbox (with binded true value) is drawn on the monitor = problem
        }
    }

    public CheckboxViewModel(XElement item, Registry registry) : base(item, registry)
    {
            ...
    }
}

view:

<DataTemplate x:DataType="viewModels:CheckboxViewModel" x:Key="CheckboxDataTemplate">
    <CheckBox IsChecked="{Binding Value}" ... />
</DataTemplate>

and my sligthly changed version of INotifyProperty:

    public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new(propertyName));
    }

    protected virtual void SetPropertyAndNotify<T>(ref T backedProperty, T newValue, [CallerMemberName] string propertyName = null)
    {
        if (object.Equals(backedProperty, newValue))
            return;

        backedProperty = newValue;

        PropertyChanged?.Invoke(this, new(propertyName));
    }
}

situation:

I put a ContentView that in BindedContext has (in some hierarchy) the CheckBoxViewModel and it is drawn. But the setter is fired.

jaydopartu
  • 63
  • 1
  • 8
  • 1
    please post the relevant code – Jason Jan 09 '23 at 18:21
  • 1
    one approach is to have a bool in your VM that is set to false. Modify PropertyChanged to not fire until that flag is set, and set it to true only after you have done whatever initialization is causing a problem – Jason Jan 09 '23 at 19:10
  • I do not know why you want this, and why do you think that drawing controls is calling the setter, but please change your design, and drop this idea. – H.A.H. Jan 09 '23 at 19:51
  • @Jason thank you. That is interesting idea. I have done a quick fix - I differentiate the "bad situation" by comparing values - if the value is not changing then I omit the further logic in setter. But I would write down your proposal, it might be even better. Thanks! – jaydopartu Jan 09 '23 at 22:41
  • @H.A.H. The situation is complex. I have registries that are known in runtime, and I am using ViewModel First approach, so I create ViewModel per each "registry" which is visualized as a View, created in hierarchy. This is even more complex. Each registry has a status if have been changed, but registry can be few bits from the whole number or a byte or a set of bytes. That is why I need further calculations in setter. I would consider dropping this approach, but maybe you would like to share some argument or proposal? You do not know anything about requirements so it seems a kind of ignorance. – jaydopartu Jan 09 '23 at 22:44
  • 1
    I would also suggest using a bool flag to control when to use `Setter` as Jason recommended. – Alexandar May - MSFT Jan 10 '23 at 09:14
  • @jaydopartu I am trying to explain to you that it is not drawing that calls setters. As for suggestions, there are many ways to skip logic in setters. This "omit changes when value is not changing" is one of the ways. If you check CommunityToolkit.MVVM, every autogenerated class for property has it. There is a way to skip first change, there is a way to skip calling the setter even. – H.A.H. Jan 10 '23 at 11:10

0 Answers0