0

I have the following item data class, as well as a converter.

class ListBoxViewItem
{
    public String Name { get; set; }
    public Boolean IsChecked { get; set; }
}

[ValueConversion(typeof(List<String>),typeof(List<ListBoxViewItem>))]
class ListToItemConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null) return null;
        IEnumerable<String> l = value as IEnumerable<String>;
        return (from n in l select new ListBoxViewItem() { IsChecked = true, Name = n });
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

class ListBoxData
{
    public List<String> AllData
    {
        get
        {
            return new List<string>()
            {
                "FOO",
                "BAR"
            };
        }
        set
        {

        }
    }
}

I bind the instance of the ListBoxData to a listbox control's ItemsSource. As below:

    <ListBox>
        <ListBox.ItemsSource>
            <Binding>
                <Binding.Path>AllData</Binding.Path>
                <Binding.Converter>
                    <local:ListToItemConverter />
                </Binding.Converter>
                <Binding.Mode>TwoWay</Binding.Mode>
            </Binding>
        </ListBox.ItemsSource>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox IsChecked="{Binding IsChecked,Mode=TwoWay}"
                          Content="{Binding Name}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

So My question is, the Convert function is called when the listbox is showing, but as every items in this list box is a checkbox, although I use TwoWay binding to bind the instance and listbox, but ConvertBack is not called when I check/uncheck the checkbox in this listbox.

I am not sure if ConvertBack is designed to work as I expected. But if I want the ConvertBack can be triggered when check status is changed, what should I do ?

winterTTr
  • 1,739
  • 1
  • 10
  • 30
  • possible duplicate of [What is the use of ConvertBack method in IValueConverter interface?](http://stackoverflow.com/questions/6424074/what-is-the-use-of-convertback-method-in-ivalueconverter-interface) – Tilak Dec 29 '12 at 15:11
  • No, I know when ConvertBack is called for a textbox control, but in my case, I want to know when ConvertBack is called for one of the item property changed in a itemscontrol. – winterTTr Dec 29 '12 at 16:16

3 Answers3

1

The ConvertBack method will fire when the Converter is used in a Binding with Mode=TwoWay. Example is whe it's used in a binding to the Text property of a TextBox. The "Convert" method will be fired when the value changes when displaying the value in the TextBox, and the "ConvertBack" will fire when the user change the TextBox value.

Mats Magnem
  • 1,375
  • 1
  • 10
  • 21
0

Add UpdateSourceTrigger to Binding and Implement ConvertBack function with reverse functionality of Convert function.

Change following

<CheckBox IsChecked="{Binding IsChecked,Mode=TwoWay}">

To

 <CheckBox IsChecked="{Binding IsChecked,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">

ConvertBack function is as follows

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    if (value is IEnumerable<ListBoxViewItem>) 
    {
      var l = (IEnumerable<ListBoxViewItem>)value;
      return l.Select(l.IsChecked);
    }

   return null;
}
Tilak
  • 30,108
  • 19
  • 83
  • 131
  • I tried in a WPF application, and add UpdateSourceTrigger, the break point in ConvertBack never triggered under debug mode. – winterTTr Dec 29 '12 at 16:13
0

You are converting ListBox.ItemsSource, not CheckBox.IsChecked

I don't think ListBox.ItemsSource will even work with a TwoWay binding since by default ListBoxes do not make changes to their ItemsSource's source collection.

If you want a converter to get run when you change CheckBox.IsChecked, then you need to specify the converter to use in the IsChecked binding

<CheckBox IsChecked="{Binding IsChecked, 
                              Converter={StaticResource MyCheckboxConverter}}"
          Content="{Binding Name}"/>

But in this case, a converter should not be needed since IsChecked is already a boolean value, so you don't need to convert it at all.

If you're trying to trigger something when your CheckBox.IsChecked changes, you're better off making sure IsChecked triggers a PropertyChange notification, and executing code in the PropertyChanged event of the class containing the IsChecked property.

Rachel
  • 130,264
  • 66
  • 304
  • 490