简体   繁体   中英

Accessing the selected element inside a templated textblock bound to a wpf listbox

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

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"));
 ...

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM