1

I am trying to get the values/contents of the "selected" check-boxes so that i can use it to get data from sqlite database in the back-end . But I am unable to get the value of the checkbox from the listview.

This is the listview -

<ListView x:Name="listview" Background="Azure" SelectionMode="Multiple"
         ItemsSource="{Binding Strings}" RenderTransformOrigin="0.5,0.5" Width="343">
    <ListView.ItemTemplate>
        <DataTemplate x:Name="datatemplate">
            <CheckBox x:Name="CheckBoxZone" IsChecked="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem},Path=IsSelected}"
                        Content="{Binding que_text}" Margin="0,5,0,0"/>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>
<Button  Style="{StaticResource ResourceKey=button_style }" x:Name="addToSurvey" Content="Add" Click="AddToSurvey_Click" />

this is the function-

private void AddToSurvey_Click(object sender, RoutedEventArgs e)
{

    //foreach (var item in listview.SelectedItems)
    for (int i=0;i< listview.SelectedItems.Count;i++)
    {
        string que = listview.Items[i].ToString(); //did not work
    }

}

this is the Questions class -

public class Questions
{
    public int que_id { get; set; }
    public string que_text { get; set; }
}

the checkbox hold the que_text value which I need to retrieve for getting the que_id from the database.

Michael
  • 3,093
  • 7
  • 39
  • 83
la27
  • 35
  • 6
  • Add a boolean `IsSelected` property to your `Questions` class. Bind that to the IsSelected property of the checkbox. If `Questions` an EF class or something, consider writing a new class that wraps it. Also consider removing the misleading plural from `Questions`, and renaming the properties to comply with normal .NET practice: `ID` (OK, semi-normal) and `Text`. – 15ee8f99-57ff-4f92-890c-b56153 Aug 19 '19 at 19:31
  • what is EF class ?(sorry for the misleading naming as well, I will rename them) Also how can I check that whether the checkbox is selected or not in the loop ? – la27 Aug 19 '19 at 19:42
  • EF is Entity Framework. The naming looked as if the class may have been generated from a database table named Questions, with columns que_id and que_text. – 15ee8f99-57ff-4f92-890c-b56153 Aug 19 '19 at 19:43
  • You could use an itemcontainerstyle like this https://stackoverflow.com/questions/15994021/listviewitem-isselected-binding-works-for-wpf-but-not-for-winrt and an IsSelected property in Question. Implement inotifypropertychanged on question. I would also probably bind ischecked of the checkbox to the new isselected property with mode twoway. – Andy Aug 19 '19 at 19:46
  • @Andy I actually tried seeing that link .I m actually new to wpf and c# and then I got more errors and I did not understand it completely, so I went ahead with this – la27 Aug 19 '19 at 19:53
  • @EdPlunkett it is not a EF class – la27 Aug 19 '19 at 19:54
  • That's great, you can make any changes to it that you need to. – 15ee8f99-57ff-4f92-890c-b56153 Aug 19 '19 at 19:54
  • If i add the IsSelected property to Question class and bind it to the checkbox IsChecked property, how should I change the value when the checkbox is checked ? and how can I get the text associated with the checkbox ? – la27 Aug 19 '19 at 20:10
  • The binding updates it when the checkbox is checked. That's what the binding does. As for the text, it's the same Question. Same object. If one has text "Bob" and user clicks the "Bob" checkbox, then the "Bob" question is `true` for `IsSelected`. Two properties of the same object in the list. In `AddToSurvey_Click`, loop through the collection of `Question` that you bound to `ItemsSource` on the ListView. Is that what `Strings` is? You should rename that, too. `Strings` isn't a good name for a list of questions. – 15ee8f99-57ff-4f92-890c-b56153 Aug 19 '19 at 20:13
  • Hang on, I see what you're doing with IsSelected. Let me whip up an example. – 15ee8f99-57ff-4f92-890c-b56153 Aug 19 '19 at 20:17
  • 1
    @EdPlunkett It worked !!! I did like u said and it worked ! Thank you so much – la27 Aug 19 '19 at 20:26

1 Answers1

2

In WPF, we use what we call MVVM. Instead of going and poking at the ListViewItem controls like in winforms, we'll put properties for the information we need on our viewmodel classes, and we'll use bindings to tell the UI how to update the viewmodel classes and vice versa.

So we'll add an IsSelected property to Question. We'll also rename that class from Questions to Question, and the collection of questions will now be named Questions instead of Strings.

public class Question
{
    public int ID { get; set; }
    public string Text { get; set; }
    public bool IsSelected { get; set; }
}

Here's your ListView. We bind CheckBox.IsSelected to ListViewItem.IsSelected, so the user can check them just by clicking anywhere on the item. Then we bind Question.IsSelected to ListViewItem.IsSelected in an ItemContainerStyle.

<ListView 
    x:Name="listview" 
    Background="Azure" 
    SelectionMode="Multiple"
    ItemsSource="{Binding Questions}" 
    >
    <ListView.ItemTemplate>
        <DataTemplate>
            <CheckBox 
                IsChecked="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}, Path=IsSelected}"
                Content="{Binding Text}" Margin="0,5,0,0"
                />
        </DataTemplate>
    </ListView.ItemTemplate>
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>
    </ListView.ItemContainerStyle>
</ListView>

And here's how we do stuff with the selected questions in that event handler. I'm guessing that your Strings collection was a member of the Window or whatever view you have; let me know if that's not the case and we'll figure out how to get to it. Remember, we're calling that collection Questions now.

private void AddToSurvey_Click(object sender, RoutedEventArgs e)
{
    string allQuestionsText = "";

    foreach (var question in Questions.Where(q => q.IsSelected))
    {
        //  I don't know what you really want to do in here, but it sounds like you do. 
        allQuestionsText += question.Text + "\n";
    }
}