1
votes

I'm pulling what's remaining of my hair out trying to get something to work in Silverlight that works out of the box in WPF.

I have some CheckBoxes on a form which represent items - The Checked property is bound to a bool in my ViewModel (one viewmodel per item). When the checkbox is checked it adds the item to a list in another ViewModel - before this happens I want to perform some validation (in my case count how many items are in the list in the other ViewModel, and if its reached a limit show the user a message) and if this validation fails don't add it to the list and uncheck the box. When it runs, after the validation check is done in the bool property setter I can see the value set back to false, but this is not reflected back in the CheckBox in the UI in Silverlight so the CheckBox remains checked. In WPF this issue does not occur.

The following code demonstrates the issue - for brevity instead of performing the validation I'm just always forcing the box to unchecked when it is checked.

XAML

<UserControl x:Class="CheckboxTest.SL.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <Grid x:Name="LayoutRoot" Background="White">
        <CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}" Margin="20"/>
    </Grid>
</UserControl>

Code Behind

namespace CheckboxTest.SL
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            this.DataContext = new MainPageViewModel();
        }
    }

    public class MainPageViewModel : INotifyPropertyChanged
    {
        private bool _isSelected;

        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                _isSelected = value;

                if (_isSelected) //if checked always uncheck
                    _isSelected = false; //this does not get reflected in UI in Silverlight

                OnPropertyChanged("IsSelected");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler changedEventHandler = this.PropertyChanged;
            if (changedEventHandler == null)
                return;
            changedEventHandler((object)this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

I know that people used to get round this issue when it was in WPF pre .NET 4.0 by either setting the property binding to Async (not allowed in Silverlight) or to implement a dummy IValueConverter (tried this and it had no effect in Silverlight).

Can anyone suggest a way to get the above to work in Silverlight please?

1

1 Answers

1
votes

One way to do this could be to bind the IsEnabled property of the CheckBox to a boolean property in your ViewModel where you can perform the validation.

public bool CanEditCheckBox
{
    get
    {
        // perform validation here
        return list.Length < 100;
    }
}

Edit

I tested your code, and it seems to work like intended.