user979033
user979033

Reputation: 6460

How to get ListView CheckBox column state

So i have ListView with CheckBox Column:

<GridViewColumn Header="Name">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal" Margin="0,0,0,0">
                <CheckBox Margin="0,0,0,0"/>
                <TextBlock x:Name="textBlock"
                       Text="{Binding Name}"
                       Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}}"
                       Style="{StaticResource TextBlockDefaultStyle}"
                       Margin="0,2,0,0"/>
            </StackPanel>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

My model have several properties like Name, Description etc and my ListView contains also simple Checkbox.

My ListView populated with several objects and i want to achieve 2 things:

  1. In case i checks specific CheckBox i want all others CheckBox to become Uncheck (in case i have another CheckBox in Checked state)

  2. How to determine the specific checked object

Upvotes: 0

Views: 52

Answers (1)

Iron
Iron

Reputation: 946

XAML:

<ListView x:Name="MyListView" SelectionChanged="MyListView_OnSelectionChanged" SelectionMode="Single">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name" Width="100">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <CheckBox>
                                <CheckBox.IsChecked>
                                    <Binding Path="IsSelected" RelativeSource="{RelativeSource AncestorType={x:Type ListViewItem}}"/>
                                </CheckBox.IsChecked>
                            </CheckBox>
                            <TextBlock Text="{Binding Name}"/>
                        </StackPanel>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Description" Width="100">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Description}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

Code-behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // some data for testing
        MyListView.ItemsSource = new List<MyData>
        {
            new MyData {Name = "123", Description = "ABC"},
            new MyData {Name = "456", Description = "EFG"},
            new MyData {Name = "789", Description = "HIJ"},
        };
    }

    private void MyListView_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (e.AddedItems != null && e.AddedItems.Count > 0)
        {
            var selectedItem = (MyData)e.AddedItems[0];
            // do something
        }
    }
}

public class MyData
{
    public string Name { get; set; }

    public string Description { get; set; }
}

Add:A clumsy way to uncheck other CheckBoxes while one is checked.

<CheckBox Checked="ToggleButton_OnChecked">
    <CheckBox.IsChecked>
        <Binding Path="IsSelected" RelativeSource="{RelativeSource AncestorType={x:Type ListViewItem}}"/>
    </CheckBox.IsChecked>
</CheckBox>

private void ToggleButton_OnChecked(object sender, RoutedEventArgs e)
{
    foreach (var checkBox in FindAllCheckBoxes(MyListView).Where(x => !ReferenceEquals(x, sender)))
    {
        checkBox.IsChecked = false;
    }
}

private static IEnumerable<CheckBox> FindAllCheckBoxes(Visual element)
{
    if (element == null)
    {
        return null;
    }

    var checkBoxes = new List<CheckBox>();
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
    {
        var visual = VisualTreeHelper.GetChild(element, i) as Visual;
        var checkBox = visual as CheckBox;

        if (checkBox != null)
        {
            checkBoxes.Add(checkBox);
        }
        else
        {
            checkBoxes.AddRange(FindAllCheckBoxes(visual));
        }
    }

    return checkBoxes;
}

Upvotes: 1

Related Questions