WPF: Is there a way to get original values in ConvertBack method of MultiValueConverter?
Asked Answered
K

2

11

I've written a MultiValueConverter which checks if a given list contains a given value and returns true if it does. I use it for binding to custom checkbox list. Now I'd like to write ConvertBack method so that if checkbox was checked, original value would be sent to the model. Is there a way to access values in ConvertBack method?

XAML:

<ListBox.ItemTemplate>
    <HierarchicalDataTemplate>
        <CheckBox Content="{Binding Path=Description}">
            <CheckBox.IsChecked>
                <MultiBinding Converter="{x:Static Classes:ListContainsMultiConverter.Instance}">
                    <Binding Path="Id" />
                    <Binding Path="DataContext.ContactTypes" RelativeSource="{RelativeSource AncestorType={x:Type Window}}" />
                </MultiBinding>
            </CheckBox.IsChecked>
        </CheckBox>
    </HierarchicalDataTemplate>
</ListBox.ItemTemplate>

I get correct results when I'm binding but is there a way to get the bound id when converting back? What I would like to achieve is that if checkbox is unchecked, the value would be removed from the list and if it is checked, the value would be added to the list.

Kesler answered 10/2, 2010 at 17:53 Comment(1)
i have a similar issue where one of my bindings in the multibinding is an object with a list of objects that contain a text field. the multibinding is bound to one of the textboxes based on the other binding value. I need the textbox to change the text of the object on convertBack, but all I have is the new value, and not what object's text needs to changeSpitter
V
7

I know this is an old issue, but this solution might help someone else.

Instead of using the the ConvertBack method of the IMultiValueConverter, you can set the IsChecked binding to be OneWay and use the CheckBox Command property to perform the check logic.

<ListBox.ItemTemplate>
    <HierarchicalDataTemplate>
        <CheckBox Content="{Binding Path=.}" Command="{Binding Path=CheckBoxCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" CommandParameter="{Binding Path=.}">
            <CheckBox.IsChecked>
                <MultiBinding Converter="{x:Static Classes:ListContainsMultiConverter.Instance}" Mode="OneWay">
                    <Binding Path="." />
                    <Binding Path="SelectedItems" RelativeSource="{RelativeSource AncestorType={x:Type Window}}" />
                </MultiBinding>
            </CheckBox.IsChecked>
        </CheckBox>
    </HierarchicalDataTemplate>
</ListBox.ItemTemplate>

Then, add the CheckBoxCommand which performs something similar to this:

    // the items bound to your checkbox
    public Collection<string> Items { get; set; }

    // the list of selected items
    public Collection<string> SelectedItems { get; set; }

    private void ExecuteCheckBoxCommand(string obj)
    {
        SelectedItems.Add(obj);
    }

I know it's a slightly round-about way of doing this but the IMultiValueConverter.ConvertBack method is really quite useless - I can't think of too many uses for it without having access to the current binding values.

Vivianne answered 14/2, 2012 at 0:15 Comment(2)
Thanks for this approach, which worked for me. It took me some time to realize that ConvertBack is completely useless. They should put that in the documentation and save us all some time.Aristarchus
Yup totally useless :(Sloop
S
5

I solved my problem, and hopefully the solution will help you too. Take the multibinding you have, and instead of putting it in the IsChecked attribute, put it in the DataContext attribute. This may be where our issues differ... in my convert method, i was using the data in the bindings to grab an object, and then i returned myobject.text. I changed this to instead return just the object, so that it gets bound to the datacontext. I then bound the textbox.text property to the text property of myobject. it seems to work fine. You could then bind the list where values are removed to the checkbox.ischecked... I guess. I'm not exactly sure what you're trying to do.

I'm thinking this might get you on the right path...

<ListBox.ItemTemplate>
<HierarchicalDataTemplate>
    <CheckBox Content="{Binding Path=Description}">
        <CheckBox.DataContext>
            <MultiBinding Converter="{x:Static Classes:ListContainsMultiConverter.Instance}">
                <Binding Path="Id" />
                <Binding Path="DataContext.ContactTypes" RelativeSource="{RelativeSource AncestorType={x:Type Window}}" />
            </MultiBinding>
        </CheckBox.DataContext>
        <CheckBox.IsChecked>
            <Binding Path="Some_Property_For_IsChecked_In_Some_Object_In_The_Converter" />
        </CheckBox.IsChecked>
    </CheckBox>
</HierarchicalDataTemplate>

Spitter answered 20/5, 2010 at 20:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.