Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8740581
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T11:09:17+00:00 2026-06-13T11:09:17+00:00

I have an MVVM-based WPF application that relies on Caliburn.Micro . In one view,

  • 0

I have an MVVM-based WPF application that relies on Caliburn.Micro.

In one view, I am displaying a DataGrid and a Button. The DataGrid displays a collection of items, where the item class derives from PropertyChangedBase.
The button should be enabled or disabled based on the contents in the editable DataGrid cells. What is the most reliable approach to achieve this with Caliburn.Micro?

Schematically, this is what my code looks right now:

public class ItemViewModel : PropertyChangedBase { }

...

public class ItemsViewModel : PropertyChangedBase
{
    private IObservableCollection<ItemViewModel> _items;

    // This is the DataGrid in ItemsView
    public IObservableCollection<ItemViewModel> Items
    {
        get { return _items; }
        set
        {
            _items = value;
            NotifyOfPropertyChange(() => Items);
        }
    }

    // This is the button in ItemsView
    public void DoWork() { }

    // This is the button enable "switch" in ItemsView
    public bool CanDoWork
    {
        get { return Items.All(item => item.NotifiableProperty == some_state); }
    }
}

As the code stands, there is no notification to ItemsViewModel.CanDoWork when one NotifiableProperty is changed, for example when the user edits one cell in the ItemsView´s DataGrid. Hence, the DoWork button enable state will never be changed.

One possible workaround is to add an (anonymous) event handler to every item in the Items collection:

foreach (var item in Items)
    item.PropertyChanged += 
        (sender, args) => NotifyOfPropertyChange(() => CanDoWork);

but then I also need to keep track of when (if) items are added or removed from the Items collection, or if the Items collection is re-initialized altogether.

Is there a more elegant and reliable solution to this problem? I am sure there is, but so far I have not been able to find it.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T11:09:18+00:00Added an answer on June 13, 2026 at 11:09 am

    I think this is a case where INPC works well; to simplify registering/deregistering adds and deletes just add a CollectionChanged handler to your Items collection:

    Items.CollectionChanged += OnItemsCollectionChanged;
    
    private void OnItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
        if (e.NewItems != null && e.NewItems.Count != 0) {
            foreach (ItemViewModel  vm in e.NewItems)
                vm.PropertyChanged += OnDetailVmChanged;
        }
        if (e.OldItems != null && e.OldItems.Count != 0) {
            foreach (ItemViewModel  vm in e.OldItems) {
                vm.PropertyChanged -= OnDetailVmChanged;
            }
        }
    }
    

    Josh Smith wrote a PropertyObserver class here that I find more elegant than shotgun INPC tracking, but in a master-detail scenario like yours you would still have to track the adds and deletes.

    EDIT by Anders Gustafsson
    Note that for the above code to work in the general case requires that Items has been initialized with the default constructor before the event handler is attached. To ensure that OnDetailVmChanged event handlers are correctly added and removed, the Items property setter need to be extended to something like this:

    public IObservableCollection<ItemViewModel> Items
    {
        get { return _items; }
        set
        {
            // If required, initialize empty _items collection and attach
            // event handler
            if (_items == null) {
                _items = new BindableCollection<ItemViewModel>();
                _items.CollectionChanged += OnItemsCollectionChanged;
            }
            // Clear old contents in _items
            _items.Clear();
            // Add value item:s one by one to _items
            if (value != null) foreach (var item in value) _items.Add(item);
    
            NotifyOfPropertyChange(() => Items);
        }
    }
    

    (And of course, with the above Items setter in place, the topmost Items.CollectionChanged event handler attachment should not be included in the code.)

    Ideally, I would have used if (value != null) _items.AddRange(value);, but when the AddRange method triggers the OnItemsCollectionChanged event handler, e.NewItems appear to be empty (or null). I have not explicitly verified that e.OldItems is non-null when the Clear() method is invoked; otherwise Clear() would also need to be replaced with one-by-one removal of the item:s in _items.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a WPF application based on PRISM that utilizes the MVVM pattern. I
In my MVVM based WPF application I have a lot of different ViewModel types
I have a small WPF application based on MVVM priniciples. So far I had
I am creating a page-based WPF application using MVVM. I have created a custom
I have created WPF MVVM application, and set WPFToolkit DataGrid binding to DataTable so
I have an MVVM application. In one of the ViewModels is the 'FindFilesCommand' which
I have a MVVM application that contains multiple views with some complex IsReadOnly rules
I have a simple WPF application where I don't have any mvvm framework like
I'm going to do a wpf application using MVVM(It based on http://www.codeproject.com/KB/WPF/MVVMQuickTutorial.aspx ). This
I'm writing a WPF application using the MVVM pattern, based on the following article:

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.