xamluwpwinrt-xamldependencyobject

UWP "form" validation event


I have a StackPanel of basic input controls. Some combinations selections are invalid. I would like to recompute the "form"s validation every time one of the inputs change. Is there some kind of event you can listen to on the parent control that will trigger when ever an observable property changes on a child?

<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <RadioButtons Header="Options:">
        <RadioButton Content="Option 1"/>
        <RadioButton Content="Option 2"/>
    </RadioButtons>
    <ToggleSwitch OnContent="On" OffContent="Off"/>
    <ComboBox>
        <ComboBoxItem Content="Item 1"/>
        <ComboBoxItem Content="Item 2"/>
    </ComboBox>
</StackPanel>

Solution

  • It is recommended to use Data Binding to listen the selection change of the controls. In Data Binding, use Binding.Mode TwoWay bindings, changes to the target will automatically propagate to the source.

    Define a class which inherits INotifyPropertyChanged, and recompute the "form"s validation in the PropertyChanged event.

    Page.xaml

    <Grid>
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" >
            <controls:RadioButtons Header="Options:" SelectedIndex="{x:Bind selectItems.RadioButtonsIndex, Mode=TwoWay}">
                <RadioButton Content="Option 1"/>
                <RadioButton Content="Option 2"/>
            </controls:RadioButtons>
            <ToggleSwitch OnContent="On" OffContent="Off" IsOn="{x:Bind selectItems.ToggleSwitchState, Mode=TwoWay}"/>
            <ComboBox SelectedIndex="{x:Bind selectItems.ComboBoxSelectIndex, Mode=TwoWay}">
                <ComboBoxItem Content="Item 1"/>
                <ComboBoxItem Content="Item 2"/>
            </ComboBox>
        </StackPanel>
    </Grid>
    

    Page.xaml.cs

    public sealed partial class MainPage : Page
    {
        public SelectItems selectItems = new SelectItems();
        public MainPage()
        {
            this.InitializeComponent();
            selectItems.PropertyChanged += SelectItems_PropertyChanged;
        }
    
        private void SelectItems_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (selectItems.RadioButtonsIndex == 1 
                && selectItems.ToggleSwitchState == true 
                && selectItems.ComboBoxSelectIndex == 1) 
            {
                Debug.WriteLine("Invalid combinations selections");
            }
        }
    }
    
    public class SelectItems: INotifyPropertyChanged
    {
        private int _radioButtonsIndex;
        private bool _toggleSwitchState;
        private int _comboBoxSelectIndex;
    
        public SelectItems()
        {
            RadioButtonsIndex = 0;
            ToggleSwitchState= false; 
            ComboBoxSelectIndex= 0;
        }
        public int RadioButtonsIndex
        {
            get => _radioButtonsIndex;
            set
            {
                _radioButtonsIndex = value;
                NotifyPropertyChanged();
            }
        }
    
        public bool ToggleSwitchState
        {
            get => _toggleSwitchState;
            set
            {
                _toggleSwitchState = value;
                NotifyPropertyChanged();
            }
        }
    
        public int ComboBoxSelectIndex
        {
            get => _comboBoxSelectIndex;
            set
            {
                _comboBoxSelectIndex = value;
                NotifyPropertyChanged();
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }