切换按钮在列表框中的点击事件
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 并且每次我单击切换时都会抛出相同的异常。
知道我做错了什么吗?谢谢
您有两个集合: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);
}
}
这是我正在处理的用户控件的一部分,一个文件名列表,我可以在其中检查 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 并且每次我单击切换时都会抛出相同的异常。
知道我做错了什么吗?谢谢
您有两个集合: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);
}
}