访问绑定到wpf列表框的模板化文本块中的选定元素

时间:2010-05-12 13:39:44

标签: c# wpf visual-studio binding

我正在尝试实现功能,但我不知道如何启动它。 我正在使用vs 2008 sp1而且我正在使用一个webservice,它返回一个集合(是contactInfo []),我将它绑定到一个ListBox上,并且上面有一个datatemplate。

<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>  

到目前为止,每项工作都很好。因此,当选中一个复选框时,我想访问属于同一行或附加到它的标签信息(或者),并将信息附加到全局变量(例如,对于每个选中的复选框)。
我现在的问题是我不知道该怎么做。
谁能说清楚如何做到这一点? 如果您注意到我计划执行操作的Checked="contacts_Checked"。感谢阅读和帮助

2 个答案:

答案 0 :(得分:3)

我听到你要求从行中获取“标签信息”,TimothyP试图解释如何做到这一点。我可以通过几种方式改进他的答案,但我想你可能不会问你真正想问的问题。

如果您想获取标签中显示的数据,那么简单的方法就是这样做。例如,使用原始模板:

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

这通常是一种更好的方法,而不是直接从标签中读取数据。

如果您想从可视树中的复选框旁边的所有标签获取所有内容,您可以这样做:

 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";
 }

我个人认为这不太好。

请注意,您也可以更改此解决方案以使用标签名称来指明要包含的标签:

 ...
   var labels = container.LogicalChildren.OfType<Label>()
     .Where(label => label.Name.StartsWith("abc"));
 ...

答案 1 :(得分:1)

我不确定我理解你的问题,但我会试一试。

您是否需要一种方法将标签信息传递给复选框 所以你可以在事件处理程序中使用该信息吗?

您可以为标签指定名称,然后使用带有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>

然后,您可以访问事件处理程序中的标记。 然而,这可能不是最佳方式。

另一个更好的选择是做这样的事情:

<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>

在此绑定中,您将找到包含CheckBox的ListBoxItem。 获得该项后,您可以访问添加到ListBox的对象:

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

然后你可以用它做你想做的事: - )

我希望这是你需要的。