3

In View, i.e. the XAML, I have binded the SelectAll bool value to the Checkbox control

<CheckBox Grid.Row="5" Content="Select All" HorizontalAlignment="Left" Margin="0,5, 0, 0"  IsChecked="{Binding Path=SelectAll, Mode=TwoWay}" Width="206"></CheckBox>

and fullfill the SelectAll as

public bool SelectAll
    {
        get { return this.Get<bool>("SelectAll"); }
        set 
        {
            this.Set<bool>("SelectAll", value);
            if (this.SelectAllCommand.CanExecute(null))
                this.SelectAllCommand.Execute(value);
        }
    }

Yes, it looks good, but I have an issue...

When all the checkboxes are selected manually, the selectall checkbox should be selected automatically... at that time, we don't want the SelectAllCommand command to be executed...

How can I do it..... I know maybe it is an easy job, but how to do it perfectly....

Thanks for giving me some advices in advance

Miyazaki
  • 1,049
  • 3
  • 10
  • 13
  • surely you want the SelectedAll property to be a Nullable – Aron Apr 08 '13 at 07:15
  • BTW what is this.Set / this.Get? – Aron Apr 08 '13 at 07:21
  • He just want to "When all the checkboxes are selected manually,..." so it is a good question +1. Sure it can be implemented on an ObservableCollectionSource.CollectionChanged event. But the question looks for a best practice. – Davut Gürbüz Apr 08 '13 at 07:22
  • Thanks Aron, this.Set / this.Get the methods that are maintaining the view element dictionary, and then we can call NotifyPropertyChanged event – Miyazaki Apr 08 '13 at 07:41
  • A helper question http://stackoverflow.com/q/1030276/413032 – Davut Gürbüz Apr 08 '13 at 11:39

2 Answers2

1

Try

public bool? SelectedAll
{
    get { return this.Get<bool?>("SelectedAll"); }
    set 
    {
        if(Equals(SelectedAll, value) == true)
            return;
        this.Set<bool?>("SelectedAll", value);
        OnSelectedAllChanged(value);
    }
}

private void SelectedAllChanged(bool? input)
{
    //Stuff
}
Aron
  • 15,464
  • 3
  • 31
  • 64
  • How you manage when all elements selected manually. What will SelectAll's state then? – Davut Gürbüz Apr 08 '13 at 07:24
  • oh, thanks for your advice, but my leader really don't like Nullable value, maybe the code will not pass his review. :( – Miyazaki Apr 08 '13 at 07:39
  • 1
    Its not a case of like or not like. This is in effect a tri-state. You either have All Selected/All Not Selected/Mixed. Hard fast rules like "I don't like nullables, therefore there should be none" are bad. Here is a business case for the tristate. All code NEEDS to be aware of the tristate. The alternative is to use a tristate enum. – Aron Apr 08 '13 at 07:48
0

You'll need to uses the PropertyChanged event of the item to reevaluate the SelectAll value anytime an items is selected.

For example,

// Setup PropertyChange notification for each item in collection
foreach(var item in MyCollection)
{
    item.PropertyChanged += Item_PropertyChanged;
}

private bool _isSelectAllExecuting = false;

// If the IsSelected property of an item changes, raise a property change 
// notification for SelectAll
void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (!_isSelectAllExecuting && e.PropertyName == "IsSelected") 
        ReevaluateSelectAll();
}

void ReevaluateSelectAll()
{
    // Will evaluate true if no items are found that are not Selected
    _selectAll = MyCollection.FirstOrDefault(p => !p.IsSelected) == null;

    // Since we're setting private field instead of public one to avoid
    // executing command in setter, we need to manually raise the
    // PropertyChanged event to notify the UI it's been changed
    RaisePropertyChanged("SelectAll");
}

void SelectAll()
{
    _isSelectAllExecuting = true;

    foreach(var item in MyCollection)
        item.IsSelected = true;

    _isSelectAllExecuting = false;
}
Rachel
  • 130,264
  • 66
  • 304
  • 490
  • I din't understand how you manage when all items selected trigger Selectall->So when SelectAll "Select All items Action" ---and go on. Stack Over Flow occurs. Maybe we need some bools or something like that to handle the SelectAll selected by manually or auto. – Davut Gürbüz Apr 09 '13 at 05:46
  • @DavutGürbüz Usually my setter will check `if (_field != value)` and only update the private field and raise a `PropertyChange` notification if the value actually changes. Changing from `true` to `true` shouldn't raise a `PropertyChange` notification. But you're right that it will raise the PropertyChange notification too many times. In those cases, I tend to just use a private bool to disable the notification while everything is being updated (I'll update my answer) – Rachel Apr 09 '13 at 11:56