locked
ToggleSwitch isOn property binding with mode=TwoWay problem

    Question

  • Hi, 

    I have a ListView with data template that include ToggleSwitch (binding mode: TwoWay for the isOn attribute) and TextBox(binding mode: Default for the text attribute), 

    those elements are bound to ObservableCollection which old an objects that include string and bool properties. 

    The binding for one side (when toggle is switch) is working - means the property change its value and raise OnPropertyChanged as expected.

    but when I change the object value the toggle switch does not response , and its "isOn" value stays as before.

    I'm using INotifyPropertyChanged and PropertyChangedEventHandler for the bound object. I also changed UpdateSourceTrigger=PropertyChanged and still nothing happens

    p.s

    When i try TwoWay binding between string and text box on the same object its work fine for both sides. 

    is there anything i'm missing ? Thank you.

    Thursday, March 5, 2015 2:48 PM

Answers

  • Hi m.s.t.l,

    >>the binding work just in one direction when i change the layer object not by the toggle switch the isOn toggle switch property does not change it status as expected .

    Based on your descrption, it seems that when you update the layer object value, the toggleswitch does not change his isOn property. Since I do not have your code which you use to update the layer object value, then I have created the following code which works very well, please try to check it:

    public sealed partial class MainPage : Page
        {
            public List<Layer> _filterList;
            public MainPage()
            {         
                this.InitializeComponent();
                _filterList=new List<Layer>();
                _filterList.Add(new Layer() { isOn = true, name = 1, iconUrl="***"});
                _filterList.Add(new Layer() { isOn = true, name = 2, iconUrl = "***" });
                _filterList.Add(new Layer() { isOn = false, name = 3, iconUrl = "***" });
                FilterListView.ItemsSource = _filterList;
            }
    
            private void ModifyLayerObjectButton_Click(object sender, RoutedEventArgs e)
            {
                //modify the isOn value
                foreach(Layer mylayer in _filterList)
                {
                    if(mylayer.name==1)
                    {
                        mylayer.isOn = false;
                        break;
                    }
                }
                //update
                FilterListView.ItemsSource = null;
                FilterListView.ItemsSource = _filterList;
            }
        }

    Please notice that in my ModifyLayerObjectButton_Click event, I have added the following lines:
    FilterListView.ItemsSource = null;
    FilterListView.ItemsSource = _filterList;
    If I do not add them, I will meet the same question as you. In my mind it may be because that when we update the Layer value in the Code Behinde, although the ItemsSource is updated, the foreground does not show the update for the toggleswitch control. So I add the above two lines as a workaround.

    If the above can not help, it will be better for you to post the code which updates the layer object in here.

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.




    Wednesday, March 18, 2015 8:27 AM
    Moderator

All replies

  • Hi m.s.t.l,

    Could you please try to post a simple reproduce project in here?

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, March 6, 2015 9:57 AM
    Moderator
  • Yes, you should post the code. Without code we can do nothing.
    Friday, March 6, 2015 10:00 AM
  • XAML : 

    <Button Name="filterButton" Content="&#xE16E;" Style="{StaticResource ButtonStyle1}" FontFamily="Segoe UI Symbol" Grid.Column="5" HorizontalAlignment="Stretch" Margin="-10,-5,1,-4" Grid.Row="5" VerticalAlignment="Stretch" Background="{x:Null}" BorderBrush="{x:Null}" FontSize="22">
                <Button.Flyout>
                    <Flyout x:Name="flyoutFilter" Placement="Bottom" FlyoutPresenterStyle="{StaticResource 				FlyoutPresenterStyle1}" Opened="Flyout_Opened_1">
                        <ScrollViewer Height="Auto" MaxHeight="250">
                            <ListView x:Name="FilterListView"
                            			ItemTemplate="{StaticResource layerListTemplate}" 				SelectionMode="None" ItemContainerStyle="{StaticResource ListViewItemStyle2}"/>
                        </ScrollViewer>
                    </Flyout>
                </Button.Flyout>

    List data template : 

    <DataTemplate x:Key="layerListTemplate">
                <Grid Margin="6" Height="35" Width="204">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="41"/>
                        <ColumnDefinition Width="86"/>
                        <ColumnDefinition Width="176"/>
                    </Grid.ColumnDefinitions>
                    <Image Source="{Binding iconUrl}" Margin="8,4,12,4"/>
                    <ToggleSwitch Name="toggleSwitch"   FlowDirection="RightToLeft" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Center" IsOn="{Binding isOn, Mode=TwoWay}" HorizontalContentAlignment="Right" Margin="0,-9,82,-2" FontSize="10.667" Toggled="ToggleSwitch_Toggled" Height="46" Style="{StaticResource ToggleSwitchStyle1}" Width="154" Grid.ColumnSpan="2"/>
                    <TextBlock Grid.Column="1" Margin="4,10,3,6" TextWrapping="Wrap" Text="{Binding name}" TextAlignment="Left" FontSize="13"/>
                </Grid>
            </DataTemplate>

    as you can see the toggle switch isOn binding is in two way mode .

    code:

    first I set the listView data context :

    FilterListView.ItemsSource = cache._filterList; 

    where _filterList is:

    public IList<Layer> _filterList;

    in each Layer object has the property 

    public class Layer : INotifyPropertyChanged
        {

    private Boolean _isOn; public Boolean isOn { get { return _isOn; } set { if (_isOn != value) { _isOn = value; OnPropertyChanged("_isOn"); } } }

    public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(String info)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(info));
                }
            }

     

    unfortunately, the binding work just in one direction when i change the layer object not by the toggle switch  the isOn toggle switch property does not change it status as expected .

    Thank you. 


    • Edited by m.s.t.l Wednesday, March 11, 2015 6:56 AM
    Wednesday, March 11, 2015 6:55 AM
  • XAML : 

    <Button Name="filterButton" Content="&#xE16E;" Style="{StaticResource ButtonStyle1}" FontFamily="Segoe UI Symbol" Grid.Column="5" HorizontalAlignment="Stretch" Margin="-10,-5,1,-4" Grid.Row="5" VerticalAlignment="Stretch" Background="{x:Null}" BorderBrush="{x:Null}" FontSize="22">
                <Button.Flyout>
                    <Flyout x:Name="flyoutFilter" Placement="Bottom" FlyoutPresenterStyle="{StaticResource 				FlyoutPresenterStyle1}" Opened="Flyout_Opened_1">
                        <ScrollViewer Height="Auto" MaxHeight="250">
                            <ListView x:Name="FilterListView"
                            			ItemTemplate="{StaticResource layerListTemplate}" 				SelectionMode="None" ItemContainerStyle="{StaticResource ListViewItemStyle2}"/>
                        </ScrollViewer>
                    </Flyout>
                </Button.Flyout>

    List data template : 

    <DataTemplate x:Key="layerListTemplate">
                <Grid Margin="6" Height="35" Width="204">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="41"/>
                        <ColumnDefinition Width="86"/>
                        <ColumnDefinition Width="176"/>
                    </Grid.ColumnDefinitions>
                    <Image Source="{Binding iconUrl}" Margin="8,4,12,4"/>
                    <ToggleSwitch Name="toggleSwitch"   FlowDirection="RightToLeft" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Center" IsOn="{Binding isOn, Mode=TwoWay}" HorizontalContentAlignment="Right" Margin="0,-9,82,-2" FontSize="10.667" Toggled="ToggleSwitch_Toggled" Height="46" Style="{StaticResource ToggleSwitchStyle1}" Width="154" Grid.ColumnSpan="2"/>
                    <TextBlock Grid.Column="1" Margin="4,10,3,6" TextWrapping="Wrap" Text="{Binding name}" TextAlignment="Left" FontSize="13"/>
                </Grid>
            </DataTemplate>

    as you can see the toggle switch isOn binding is in two way mode .

    code:

    first I set the listView data context :

    FilterListView.ItemsSource = cache._filterList; 

    where _filterList is:

    public IList<Layer> _filterList;

    in each Layer object has the property 

    public class Layer : INotifyPropertyChanged
        {

    private Boolean _isOn; public Boolean isOn { get { return _isOn; } set { if (_isOn != value) { _isOn = value; OnPropertyChanged("_isOn"); } } }

    public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(String info)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                {
                    handler(this, new PropertyChangedEventArgs(info));
                }
            }

     

    unfortunately, the binding work just in one direction when i change the layer object not by the toggle switch  the isOn toggle switch property does not change it status as expected .

    Thank you. 

    Thursday, March 12, 2015 12:04 PM
  • Hi m.s.t.l,

    >>the binding work just in one direction when i change the layer object not by the toggle switch the isOn toggle switch property does not change it status as expected .

    Based on your descrption, it seems that when you update the layer object value, the toggleswitch does not change his isOn property. Since I do not have your code which you use to update the layer object value, then I have created the following code which works very well, please try to check it:

    public sealed partial class MainPage : Page
        {
            public List<Layer> _filterList;
            public MainPage()
            {         
                this.InitializeComponent();
                _filterList=new List<Layer>();
                _filterList.Add(new Layer() { isOn = true, name = 1, iconUrl="***"});
                _filterList.Add(new Layer() { isOn = true, name = 2, iconUrl = "***" });
                _filterList.Add(new Layer() { isOn = false, name = 3, iconUrl = "***" });
                FilterListView.ItemsSource = _filterList;
            }
    
            private void ModifyLayerObjectButton_Click(object sender, RoutedEventArgs e)
            {
                //modify the isOn value
                foreach(Layer mylayer in _filterList)
                {
                    if(mylayer.name==1)
                    {
                        mylayer.isOn = false;
                        break;
                    }
                }
                //update
                FilterListView.ItemsSource = null;
                FilterListView.ItemsSource = _filterList;
            }
        }

    Please notice that in my ModifyLayerObjectButton_Click event, I have added the following lines:
    FilterListView.ItemsSource = null;
    FilterListView.ItemsSource = _filterList;
    If I do not add them, I will meet the same question as you. In my mind it may be because that when we update the Layer value in the Code Behinde, although the ItemsSource is updated, the foreground does not show the update for the toggleswitch control. So I add the above two lines as a workaround.

    If the above can not help, it will be better for you to post the code which updates the layer object in here.

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.




    Wednesday, March 18, 2015 8:27 AM
    Moderator