切换按钮在列表框中的点击事件

togglebutton's click event in listbox

这是我正在处理的用户控件的一部分,一个文件名列表,我可以在其中检查 select 其中一些的切换按钮 :

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

现在,当我点击切换按钮时,我会引发此事件:

    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 的 adding/removing 文件名 :

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

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

当我测试用户控件时,随机检查切换按钮,我可以通过调试器看到集合中的某些文件名重复,当发生这种情况时,将抛出异常 E0434352。

此外,FileSelected 现在是一个 observablecollection,但如果我将它设为 observablecollection 类型的依赖属性以便能够绑定它,那么它始终为 null 并且每次我单击切换时都会抛出相同的异常。

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

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

您的变量 index 有一个 FileDisplay 的索引。您 运行 遇到麻烦的地方是您也将它用作 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);
    }
}