ListView 仅在单击时删除
我有一个带有特定 ItemTemplate 的 ListView,它直观地显示对象列表的内容。我想允许用户通过单击来选择这样的对象,选择它的结果是,它将作为应用程序的当前对象加载并从列表中删除。
问题是列表视图不支持 Click 事件,所以我尝试使用 SelectionChanged 事件。好吧,这也不好,因为如果我单击一个项目(但不释放鼠标),然后将鼠标移到另一个项目上(同时按住鼠标),它也会删除该项目。
关于如何从列表中删除所选项目而不触发其他操作有什么建议吗?这是我的代码的简化版本(具有相同的行为):
<Window x:Class="ListViewIssue.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>
<ListView x:Name="lstNumbers" SelectionMode="Single" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionChanged="lstNumbers_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width="170" Background="Transparent">
<TextBlock HorizontalAlignment="Left" Text="{Binding val, Mode=TwoWay}" TextWrapping="Wrap" Margin="3"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Name="btnAddItem" Grid.Row="1" Click="btnAddItem_Click">Add Item</Button>
</Grid>
</Window>
以及背后的代码:
public partial class MainWindow : Window
{
public class valueClass
{
public int val { get; set; }
}
private List<valueClass> list;
private int counter;
public MainWindow()
{
InitializeComponent();
CreateList();
DisplayList();
}
private void CreateList()
{
list = new List<valueClass>();
counter = 8;
for (int i = 0; i < counter; i++)
{
list.Add(new valueClass() { val = i + 1 });
}
}
private void lstNumbers_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (lstNumbers.SelectedIndex != -1)
{
list.Remove(lstNumbers.SelectedValue as valueClass);
DisplayList();
}
}
private void DisplayList()
{
this.lstNumbers.ItemsSource = null;
this.lstNumbers.ItemsSource = list;
}
private void btnAddItem_Click(object sender, RoutedEventArgs e)
{
list.Add(new valueClass() { val = counter++ + 1 });
DisplayList();
}
}
I have a ListView with a specific ItemTemplate, which visually displays the contents of a list of objects. I wanted to allow the user to select such an object by clicking on it, and as a consequence of selecting it, it will be loaded as the application's current object and deleted from the list.
The problem is that the listview doesn't support Click events, so I tried using the SelectionChanged event. Well, this isn't ok as well, because if I click on an item (but without releasing the mouse) and then I move the mouse over another item (while keeping the mouse pressed), it deletes that item as well.
Any suggestions on how I can delete the selected item from the list without triggering additional operations? here's a simplified version of my code (which has the same behaviour):
<Window x:Class="ListViewIssue.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>
<ListView x:Name="lstNumbers" SelectionMode="Single" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectionChanged="lstNumbers_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width="170" Background="Transparent">
<TextBlock HorizontalAlignment="Left" Text="{Binding val, Mode=TwoWay}" TextWrapping="Wrap" Margin="3"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Name="btnAddItem" Grid.Row="1" Click="btnAddItem_Click">Add Item</Button>
</Grid>
</Window>
and code behind:
public partial class MainWindow : Window
{
public class valueClass
{
public int val { get; set; }
}
private List<valueClass> list;
private int counter;
public MainWindow()
{
InitializeComponent();
CreateList();
DisplayList();
}
private void CreateList()
{
list = new List<valueClass>();
counter = 8;
for (int i = 0; i < counter; i++)
{
list.Add(new valueClass() { val = i + 1 });
}
}
private void lstNumbers_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (lstNumbers.SelectedIndex != -1)
{
list.Remove(lstNumbers.SelectedValue as valueClass);
DisplayList();
}
}
private void DisplayList()
{
this.lstNumbers.ItemsSource = null;
this.lstNumbers.ItemsSource = list;
}
private void btnAddItem_Click(object sender, RoutedEventArgs e)
{
list.Add(new valueClass() { val = counter++ + 1 });
DisplayList();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我把它放在一个答案中,这样它就可以从评论墙上脱颖而出。
由于您要在选择更改时删除,因此只要发生更改,您就将删除。尝试在 PreviewMouseUp 中使用删除逻辑,然后抓取那里的项目。这样,在单击完成之前,单击某项不会删除该项目。
希望这有帮助。
I put this in an answer so it stands out from the comment wall there.
Since you are removing on selectionchanged, anytime that changes, you're deleting. Try using your remove logic in PreviewMouseUp and then grabbing the item there. That way, clicking down on something won't remove the item until you're click is finished.
Hope this helps.
您应该尝试避免代码隐藏,并采用 MVVM 设计模式。在这种情况下,您将绑定
ListView
的SelectedItem
(尽管没有理由这不能是ListBox
),并且然后只需从集合中删除视图模型中的SelectedItem
即可响应其值的更改。You should try and avoid code behind, and adopt the MVVM design pattern. In this case, you would bind the
SelectedItem
of theListView
(although there is no reason this couldn't be aListBox
instead), and then just remove theSelectedItem
in your view model from the collection in response a change in its value.我的解决方案
My Solution