这是我正在处理的用户控件的一部分,一个文件名列表,我可以在其中检查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并且每次单击切换时抛出相同的异常。
知道我做错了什么吗?谢谢
答案 0 :(得分:1)
您有两个集合:FileDisplay
和FileSelected
。 FileSelected
包含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);
}
}