ListView 仅在单击时删除

发布于 2024-12-10 21:50:23 字数 2822 浏览 1 评论 0原文

我有一个带有特定 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

讽刺将军 2024-12-17 21:50:23

我把它放在一个答案中,这样它就可以从评论墙上脱颖而出。

由于您要在选择更改时删除,因此只要发生更改,您就将删除。尝试在 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.

挥剑断情 2024-12-17 21:50:23

您应该尝试避免代码隐藏,并采用 MVVM 设计模式。在这种情况下,您将绑定 ListViewSelectedItem(尽管没有理由这不能是 ListBox),并且然后只需从集合中删除视图模型中的 SelectedItem 即可响应其值的更改。

You should try and avoid code behind, and adopt the MVVM design pattern. In this case, you would bind the SelectedItem of the ListView (although there is no reason this couldn't be a ListBox instead), and then just remove the SelectedItem in your view model from the collection in response a change in its value.

闻呓 2024-12-17 21:50:23

我的解决方案

private void lstNumbers_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lstNumbers.SelectedIndex != -1)
            { 
                lstNumbers.SelectionChanged-=lstNumbers_SelectionChanged;
                list.Remove(lstNumbers.SelectedValue as valueClass);
                DisplayList();
                lstNumbers.SelectionChanged+=lstNumbers_SelectionChanged;
            }
        }

My Solution

private void lstNumbers_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lstNumbers.SelectedIndex != -1)
            { 
                lstNumbers.SelectionChanged-=lstNumbers_SelectionChanged;
                list.Remove(lstNumbers.SelectedValue as valueClass);
                DisplayList();
                lstNumbers.SelectionChanged+=lstNumbers_SelectionChanged;
            }
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文