通过列表框迭代不能正确返回?

时间:2012-01-09 17:21:29

标签: c# .net wpf silverlight xaml

我有一个复选框列表框,我想要迭代并检查所有复选框,并取消选中它们。我还需要找到稍后检查的那些。这是我的代码:

<StackPanel>
    <StackPanel Orientation="Horizontal">
        <TextBlock Style="{StaticResource TextLabel}" Text="Building Houses Organization:"></TextBlock>
        <TextBlock Text="All" Margin="136,0,0,0" Foreground="#FF001BFF" FontSize="11" VerticalAlignment="Center" Tag="{Binding ElementName=BuildingsOrganizationList}" MouseLeftButtonDown="CheckAll"/>
        <TextBlock Text=" | " VerticalAlignment="Center"/>
        <TextBlock Text="None" Foreground="#FF001BFF" FontSize="11" VerticalAlignment="Center" Tag="{Binding ElementName=BuildingsOrganizationList}" MouseLeftButtonDown="CheckNone"/>
    </StackPanel>
    <ListBox x:Name="BuildingsOrganizationList" HorizontalAlignment="Left" VerticalAlignment="Top" Width="{Binding ActualWidth, ElementName=BuildingOrganizationGrid, Mode=OneWay}" Height="141">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</StackPanel>

你可以看到我的文本块有一个标签绑定到我的列表框,其中包含我的复选框。现在在后面的代码中我有以下内容:

private void CheckAll(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    TextBlock textblock = sender as TextBlock;
    ListBox list = textblock.Tag as ListBox;
    foreach (ListBoxItem item in list.Items)
    {
        //.....
    }
}

问题是这些项目是字符串。它们不是ListBoxItem或CheckBox对象。那是为什么?

修改

我现在已经添加了这个类

class ListItem
{
    private string _name;
    private bool? _isChecked;

    public ListItem()
    {
        _name = "";
        _isChecked = null;
    }

    public ListItem(string name, bool? isChecked)
    {
        Name = name;
        IsChecked = isChecked;
    }

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public bool? IsChecked
    {
        get { return _isChecked; }
        set { _isChecked = value; }
    }
}

并填写以下行以填充我的列表

BuildingsOrganizationList.Items.Add(new ListItem(org, true));

和XAML:

    <ListBox x:Name="BuildingsOrganizationList" HorizontalAlignment="Left" VerticalAlignment="Top" Width="{Binding ActualWidth, ElementName=BuildingOrganizationGrid, Mode=OneWay}" Height="141">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

但是,我的复选框没有被选中,也没有文字。

2 个答案:

答案 0 :(得分:1)

我的猜测是因为您使用BuildingsOrganizationList.Items.Add(someString)使用Items填充ListBox。

ListBox.Items将返回绑定到ListBox的数据对象,而不是UI对象。因此,如果您的数据对象是字符串,那么ListBox.Items将返回一组字符串。如果您想获取与数据对象相关的UI对象,则需要使用ListBox的ItemContainerGenerator并调用.ContainerFromItem(dataItem)

最好使用IsChecked属性并绑定IsChecked CheckBox值的对象填充ListBox。这是因为默认情况下,WPF将使用Virtualized ListBoxes,在滚动时回收UI控件,这意味着CheckBoxes将失去IsChecked值,除非它们被绑定到某些东西。

例如,

BuildingsOrganizationList.Items.Add(new SomeItem { Name="A", IsChecked=false });
BuildingsOrganizationList.Items.Add(new SomeItem { Name="B", IsChecked=false });
BuildingsOrganizationList.Items.Add(new SomeItem { Name="C", IsChecked=false });

ListBox的DataTemplate

<DataTemplate>
    <CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}" />
</DataTemplate>

然后你可以使用

private void CheckAll(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    foreach (SomeItem item in BuildingsOrganizationList.Items)
    {
        item.IsChecked = true;
    }
}

答案 1 :(得分:0)

我们怎么知道?您添加了这些项目,然后将它们绑定到Content的{​​{1}},意味着您的项目变为CheckBoxes

如果您想访问模板的CheckBoxes,虽然您可以通过各种令人讨厌的方式获取它,但我推荐任何模板。

将项目类型更改为具有can be boundCheckBox bool属性的某个类。更清洁,更容易处理。通常,在大多数情况下,您不需要在代码中引用任何实际控件,尝试绑定必要的属性。 (也不需要对ListBox的引用:绑定CheckBox.IsChecked,迭代它,更改项目的属性)