views:

79

answers:

2

Hello good people , i'm trying to achieve a functionality but i'm don't know how to start it. I'm using vs 2008 sp1 and i'm consuming a webservice which returns a collection (is contactInfo[]) that i bind to a ListBox with little datatemplate on it.

<ListBox Margin="-146,-124,-143,-118.808" Name="contactListBox" MaxHeight="240" MaxWidth="300" MinHeight="240" MinWidth="300">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock>
                              <CheckBox Name="contactsCheck" Uid="{Binding fullName}" Checked="contacts_Checked" /><Label Content="{Binding fullName}" FontSize="15" FontWeight="Bold"/> <LineBreak/>
                              <Label Content="{Binding mobile}" FontSize="10" FontStyle="Italic" Foreground="DimGray" />  <Label Content="{Binding email}" FontStyle="Italic" FontSize="10" Foreground="DimGray"/>
                            </TextBlock>

                        </DataTemplate>
                    </ListBox.ItemTemplate>
   </ListBox>  

Every works fine so far. so When a checkbox is checked i'll like to access the information of the labels (either the) belonging to the same row or attached to it and append the information to a global variable for example (for each checkbox checked).
My problem right now is that i don't know how to do that.
Can any one shed some light on how to do that? if you notice Checked="contacts_Checked" that's where i planned to perform the operations. thanks for reading and helping out

+1  A: 

I'm not exactly sure I understand your question, but I'll give it a shot.

Do you need a way to pass the information of the labels to the checkbox so you can use that information in the event handler ?

You can give the label a name and then using a binding with ElementName

<ListBox Margin="-146,-124,-143,-118.808" Name="contactListBox" MaxHeight="240" MaxWidth="300" MinHeight="240" MinWidth="300">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock>
                        <CheckBox Name="contactsCheck" Uid="{Binding fullName}" Checked="contacts_Checked" Tag="{Binding ElementName=lblMobile,Path=Content}" /><Label Content="{Binding fullName}" FontSize="15" FontWeight="Bold"/> <LineBreak/>
                        <Label Name="lblMobile" Content="{Binding mobile}" FontSize="10" FontStyle="Italic" Foreground="DimGray" />  <Label Content="{Binding email}" FontStyle="Italic" FontSize="10" Foreground="DimGray"/>
            </TextBlock>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

You could then get to the tag in the event handler. However this is probably not the best way to go.

Another, and better option would be do something like this:

<ListBox Margin="-146,-124,-143,-118.808" Name="contactListBox" MaxHeight="240" MaxWidth="300" MinHeight="240" MinWidth="300">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock>
                        <CheckBox Name="contactsCheck" Uid="{Binding fullName}" Checked="contacts_Checked">
                            <CheckBox.Tag>
                                <Binding>
                                <Binding.RelativeSource>
                                <RelativeSource
                                    Mode="FindAncestor"
                                    AncestorType="{x:Type ListBoxItem}"
                                    AncestorLevel="1"
                                />
                                </Binding.RelativeSource>
                            </Binding>
                            </CheckBox.Tag>
                        </CheckBox>
                            <Label Content="{Binding fullName}" FontSize="15" FontWeight="Bold"/> <LineBreak/>
                        <Label Name="lblMobile" Content="{Binding mobile}" FontSize="10" FontStyle="Italic" Foreground="DimGray" />  <Label Content="{Binding email}" FontStyle="Italic" FontSize="10" Foreground="DimGray"/>
            </TextBlock>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

In this binding, you go and find the ListBoxItem in which the CheckBox is contained. Once you have that Item you can get to the object that you added to the ListBox:

private void contacts_Checked(object sender, RoutedEventArgs e)
{
    var checkBox = sender as CheckBox;
    var listBoxItem = (checkBox.Tag as ListBoxItem);
    var dataItem = listBoxItem.Content;
}

Then you can do with it what you want :-)

I hope this is what you need.

TimothyP
Thanks bruv! thanks a lot, this gives me some idea, but what i meant is that when i checked a checkbox on a row i 'll like to get the label of the same row.On way to achieve what i'll like to do at the end will be: when i check a checkbox i get the objet of the lixtbox of that index selected too. i think the second one will be easier. thanks for the trial ,i'll dig more into it
black sensei
In your DataTemplate you have 2 Labels, which one do you want to get?You could change the Binding in the first example to this:{Binding ElementName=lblMobile,Path=.}But I'm still not sure that's what you mean :p
TimothyP
@TimothyP: Several hopefully-helpful notes from the expert: 1. The binding you have for Tag can be more easily expressed as `Tag="{Binding RelativeSource={RelativeSource FindAncestor,ListBoxItem,1}}"`. 2. Your use of "Tag" is actually unnecessary since DataContext points to the dataItem itself. 3. For this technique, FindName() may possibly be more appropriate than ElementName=. 4. See my answer for an arguably better way altogether. 5. General principle: If you ever use "Tag" in WPF you're almost certainly doing something the hard way.
Ray Burns
@Ray-Burns +1, I agree and I'll remember that :-)
TimothyP
+2  A: 

I hear you asking to get the "information of the labels" from the row, and TimothyP has tried to explain how to do that. I could improve on his answer in several ways, but I think you are probably not asking the question you really meant to ask.

If you want to get the data that is displayed in the labels, the easy way is to simply do that. For example, with your original template:

 private void contactscheck_Checked(object sender, EventArgs e)
 {
   var data = DataContext as MyDataObjectType;
   globalVariable += data.fullname + " " + data.mobile + "\r\n";
 }

This is generally a better way to do things than to read data directly out of labels.

If you want to get all Content from all the labels beside the checkbox in the visual tree, you can do it like this:

 private void contactscheck_Checked(object sender, EventArgs e)
 {
   var checkbox = sender as CheckBox;
   var container = (FrameworkElement)checkbox.Parent;
   var labels = container.LogicalChildren.OfType<Label>();
   var labelText = string.Join(" ",
     (from label in labels select label.Content.ToString()).ToArray());
   globalVariable += labelText + "\r\n";
 }

Personally I don't think this is as nice.

Note that you can also change this solution to use the label name to indicate which labels you want to include:

 ...
   var labels = container.LogicalChildren.OfType<Label>()
     .Where(label => label.Name.StartsWith("abc"));
 ...
Ray Burns
Thanks Man that's nice, I got new ideas from this.Could you show me how to trigger listbox selectionChanged handler when one checks on the checkbox? thanks man , really
black sensei
Sure. `<CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor,ListBoxItem,1}}" />`. Now the checkbox will be checked whenever the item is selected, and clicking the checkbox will select the item.
Ray Burns
Do I get an up vote? Or better yet, a green "best answer" checkmark?
Ray Burns
lol you'll get a vote up man. and nice solution.
black sensei
Hey! Dude i just realized that i can't use the second contactscheck_Checked handler that you sugested for a case where i'll like to provide check all/uncheck all.i guess those button/links are outside the Listbox and the only workaround is to set another globalvariable to hold the contactscheck_Checked sender Object for me to use same logic you suggested to access all the checkboxes.what do you think? thanks for you next reply ^^
black sensei
Yep, upvote from me to you as well :-)
TimothyP
You can't select all items in a ListBox unless its SelectionMode=Multiple or SelectionMode=Extended. If so, all you need to do is `contactListBox.SelectedItems.Clear()` to uncheck all the checkboxes and `contactListBox.SelectedItems.Clear(); foreach(var item in contactListBox.Items) contactListBox.SelectedItems.Add(item);` to check all the checkboxes
Ray Burns