1

I have a ListView with checkboxes like this:

<ListView 
    x:Name="usersListView"
    Width="300"
    ItemsSource="{Binding}"
    IsSynchronizedWithCurrentItem="True"
    SelectionChanged="childrenListView_SelectionChanged"
    Background="{StaticResource BackgroundPrimaryBrush}"
    Foreground="{StaticResource WhiteBrush}"
    Grid.Row="6" Grid.ColumnSpan="2"
    >
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn>
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox Tag="{Binding Id}" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListViewItem}}, Path=IsSelected}" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn DisplayMemberBinding="{Binding FullName}" Header="Name" Width="250"/>
            </GridView.Columns>
        </GridView>
    </ListView.View>
</ListView>

All checkboxes in ListView are from List 'AllUsers' from database. Now I want to set specific checkboxes to IsChecked=True in code behind. I have another List 'Children' which have only few of the 'AllUsers' elements. What I want is to display ListView with selected checkboxed binded to Persons in 'Children'.

I tried to implement this by myself with INotifyPropertyChanged implemented class wrapper to Person but I couldn't get Binding properly with this.

I hope I did explain the problem properly. Thank you in advance :)

1
  • Set the Id property of the items you want to select to true. Commented Jun 13, 2018 at 13:54

1 Answer 1

2

Consider using a IMultiValueConverter.

In the example below, my Children object is a simple string with the name. I have two list, the AllChildrens list and the SelectedChildrens list.

Foreach element in the AllChildrens collection, the converter checks if the element is contained into SelectedChildrens collection.

XAML: (I've removed the events)

<ListView ItemsSource="{Binding AllChildrens}" Tag="{Binding SelectedChildrens}">
    <ListView.Resources>
        <local:IEnumerableContainsConverter x:Key="Contains" />
    </ListView.Resources>
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn>
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox Content="{Binding}">
                                <CheckBox.IsChecked>
                                    <MultiBinding Converter="{StaticResource Contains}">
                                        <Binding Path="." />
                                        <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type ListView}}" Path="Tag" />
                                    </MultiBinding>
                                </CheckBox.IsChecked>
                            </CheckBox>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn DisplayMemberBinding="{Binding FullName}" Header="Name" Width="250"/>
            </GridView.Columns>
        </GridView>
    </ListView.View>
</ListView>

ViewModel:

public class Model
{
    public Model()
    {
        AllChildrens = new List<string>()
        {
            "James",
            "Annabelle",
            "Kevin",
            "William",
            "Joseph",
        };

        SelectedChildrens = new List<string>()
        {
            "James",
            "Annabelle",
            "William",
        };
    }

    public List<string> AllChildrens { get; set; }
    public List<string> SelectedChildrens { get; set; }
}

Converter:

class IEnumerableContainsConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values != null &&
            values.Length == 2 &&
            values[0] is string current_children && // Replace with your children object type
            values[1] is IEnumerable<string> selected) // Replace with your children object type
        {
            return selected.Contains(current_children);
        }

        return false;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.