togglebutton在列表框中的点击事件

时间:2016-03-23 19:34:59

标签: c# wpf user-controls listbox observablecollection

这是我正在处理的用户控件的一部分,一个文件名列表,我可以在其中检查togglebutton以选择其中一些:

<ListBox x:Name="FileListBox" Template="{DynamicResource BaseListBoxControlStyle}" Grid.RowSpan="5" Grid.Row="1" Margin="0" ItemContainerStyle="{DynamicResource BaseListBoxItemStyle}" ItemsSource="{Binding DataContext.FileDisplay, ElementName=F_Selector, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalContentAlignment="Stretch">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <DockPanel>
                        <Button x:Name="ListDelete" Width="{Binding ActualHeight, ElementName=ListDelete}" Style="{DynamicResource BaseButtonStyle}" Margin="4,0,0,0" DockPanel.Dock="Right" Content="X" Click="FileDelete_Click"/>
                        <StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
                            <ToggleButton x:Name="ListCheck" Click="ListCheck_Click" Width="{Binding ActualHeight, ElementName=ListCheck}"  Margin="0,0,4,0" />
                            <TextBlock Text="{Binding ., Converter={StaticResource PathToFileName}}"/>
                        </StackPanel>
                    </DockPanel>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

现在当我点击一个togglebutton时,我提出了这个事件:

    private void ListCheck_Click(object sender, RoutedEventArgs e)
    {
        ToggleButton btn = (ToggleButton)sender;
        int index = FileListBox.Items.IndexOf(btn.DataContext);
        if (btn.IsChecked == true)
        {
            FileSelected.Add(FileDisplay[index]);
        }
        else
        {
            FileSelected.RemoveAt(index);
        }
    }

所以我在这个observablecollection中添加/删除文件名:

    private ObservableCollection<string> _FileSelected = new ObservableCollection<string>();
    public ObservableCollection<string> FileSelected
    {
        get { return _FileSelected; }
        set { _FileSelected = value; }
    }

在我的最终项目中,此列表框usercontrol包含在另一个用户控件中,该控件使用了6次到(最终)一个。

当我测试usercontrol,随机检查togglebuttons时,我可以看到调试器中某些文件名在集合中重复,当发生这种情况时,会抛出异常E0434352。

此外,FileSelected现在是一个observablecollection,但如果我使它成为observablecollection类型的依赖项属性能够绑定它,那么它总是为null并且每次单击切换时抛出相同的异常。

知道我做错了什么吗?谢谢

1 个答案:

答案 0 :(得分:1)

您有两个集合:FileDisplayFileSelectedFileSelected包含FileDisplay中项目的子集,有时是空子集。

您的变量indexFileDisplay的索引。在遇到麻烦的地方,您也将其用作FileSelected的索引。这是一个问题,因为在几乎所有情况下,这两个集合不包含相同顺序的相同项目。

假设您在FileDisplay中有五个项目,用户选择FileDisplay[2],并将该项目添加到FileSelected。然后他取消选择该项目,然后删除FileSelected[2]。它会引发异常,因为FileSelected只有一个项目,索引为0

然后,您可以通过不弄乱索引来简化它。 ObservableCollection<T>.Remove(T)应该可以正常工作。

private void ListCheck_Click(object sender, RoutedEventArgs e)
{
    ToggleButton btn = (ToggleButton)sender;
    int index = FileListBox.Items.IndexOf(btn.DataContext);
    var item = FileDisplay[index];

    //  This will probably work instead of messing with the index:
    //  var item = btn.DataContext as WhateverTypeFileSelectedContains;

    //  No need to compare a bool to true. 
    if (btn.IsChecked)
    {
        FileSelected.Add(item);
    }
    else if (FileSelected.Contains(item))
    {
        FileSelected.Remove(item);
    }
}