Click here to Skip to main content
15,400,282 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a user control with a few toggle buttons. When a button is clicked, I'd like the index of the button to be bound to a 'SelectedIndex'. So far, using the element Tag for the index, this works fine. But now I'd like to be able to set the SelectedIndex from outside of the UserControl and the correct ToggleButton should be marked as IsChecked. This is the point where I'm stuck trying to do all this from XAML.
Should I make ViewModel with a property bound to each ToggleButtons IsChecked value? - There must be a better approach to somehow bind this both ways.

This is really just trying to create my own radiolist control.

What I have tried:

So far, click one of the buttons updates the SelectedIndex from inside the UserControl.
C#
    public int SelectedIndex
        {
            get => (int)GetValue(SelectedIndexProperty);
            set => SetValue(SelectedIndexProperty, value);
        }


        public static readonly DependencyProperty SelectedIndexProperty =
            DependencyProperty.Register("SelectedIndex", typeof(int), typeof(ToolBarControl), new PropertyMetadata(0));

        private void ToggleButton_Click(object sender, RoutedEventArgs e)
        {
            if (sender is ToggleButton btn)
            {
                SelectedIndex = int.Parse(btn.Tag.ToString());
            }
            ToggleAllButtonsState((ToggleButton)sender);
        }
        
// check the click button, and uncheck all the others in the panel
        private void ToggleAllButtonsState(ToggleButton buttonToCheck)
        {
            foreach (var item in ToggleButtonsPanel.Children)
            {
                if (item is ToggleButton toggleButton)
                {
                    if (toggleButton == buttonToCheck)
                    {
                        SelectedIndex = int.Parse(toggleButton.Tag.ToString()); 
                    }

                    toggleButton.IsChecked = (toggleButton == buttonToCheck);
                }
            }
        }


XAML
<StackPanel x:Name="ToggleButtonsPanel">         
<ToggleButton Tag="0" Click="ToggleButton_Click" />
<ToggleButton Tag="1" Click="ToggleButton_Click" />
<ToggleButton Tag="2" Click="ToggleButton_Click" />
</StackPanel>
Posted
Updated 23-Nov-20 22:25pm
Comments
Gerry Schmitz 19-Nov-20 17:26pm
   
If you explained the point to all this, someone might offer a (better) solution. Right now, it all seems pointless.

I've managed to do what I was hoping to achieve by using a converter parameter. Checking one of the three checkboxes, updates the value of SelectedIndex. Entering the value of SelectedIndex into the textbox will check the correct checkbox and uncheck the others.


XML
<!-- the view using the UserControl -->
   <StackPanel Orientation="Horizontal" Height="70">
       <local:ButtonTest SelectedIndex="{Binding SelectedIndex}" />
       <TextBox Width="100" Text="{Binding SelectedIndex, Mode=TwoWay}" />
       <Button Content="Update UserControl" />
   </StackPanel>
XML
<!-- the usercontrol -->
  <UserControl.Resources>
       <cnvtr:EquatorToBoolConverter x:Key="EquatorToBoolConverter" />
   </UserControl.Resources>
   <StackPanel Orientation="Horizontal">

       <CheckBox Content="One"
                 IsChecked="{Binding SelectedIndex, Converter={StaticResource EquatorToBoolConverter}, ConverterParameter=1}"/>
       <CheckBox Content="Two"
                 IsChecked="{Binding SelectedIndex, Converter={StaticResource EquatorToBoolConverter}, ConverterParameter=2}" />
       <CheckBox Content="Three"
                 IsChecked="{Binding SelectedIndex, Converter={StaticResource EquatorToBoolConverter}, ConverterParameter=3}" />
       <TextBlock Margin="10"
                  Padding="10"
                  FontWeight="Black"
                  Text="{Binding SelectedIndex}"/>

   </StackPanel>
C#
// usercontrol code behind.
   public partial class ButtonTest : UserControl
   {
       public ButtonTest()
       {
           InitializeComponent();
       }

       public int SelectedIndex
       {
           get => (int)GetValue(SelectedIndexProperty);
           set => SetValue(SelectedIndexProperty, value);
       }

       public static readonly DependencyProperty SelectedIndexProperty =
           DependencyProperty.Register("SelectedIndex", typeof(int), typeof(ButtonTest), new PropertyMetadata(0));
   }
C#
// the converter
  class EquatorToBoolConverter : IValueConverter
  {
      public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
      {
          return (value.ToString() == parameter.ToString());
      }

      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
      {
          var actualValue = (bool)value;
          var param = int.Parse(parameter.ToString());

          return actualValue ? param : 0;
      }
  }
C#
// the view model
        private int _selectedIndex;
        public int SelectedIndex
        {
            get => _selectedIndex;
            set
            {
                if (_selectedIndex != value)
                {
                    _selectedIndex = value;
                    OnPropertyChanged();
                }
            }
        }
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900