代码之家  ›  专栏  ›  技术社区  ›  black sensei

访问绑定到WPF列表框的模板化文本块内的所选元素

  •  0
  • black sensei  · 技术社区  · 15 年前

    我试图实现一个功能,但我不知道如何启动它。 我使用的是VS2008SP1,我使用的是一个WebService,它返回一个集合(即contactInfo[]),我将它绑定到一个列表框,上面只有一个小的数据模板。

    <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 回复  |  直到 15 年前
        1
  •  3
  •   Ray Burns    15 年前

    我听说你要求从这一行获得“标签信息”,蒂莫西普试图解释如何做到这一点。我可以从几个方面改进他的回答,但我认为你可能不会问你真正想问的问题。

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

     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"));
     ...
    
        2
  •  1
  •   TimothyP    15 年前

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

    是否需要将标签信息传递给复选框 所以您可以在事件处理程序中使用这些信息?

    可以为标签命名,然后使用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>
    

    在这个绑定中,您可以找到包含复选框的ListBoxItem。 一旦拥有了该项,就可以访问添加到列表框中的对象:

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

    然后你可以随心所欲地使用它:-)

    我希望这是你需要的。