首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >单击并拖动到WPF/C#中的多重复选框

问题:

我的应用程序要求用户能够通过一列复选框在一个数据集中选择多个条目。所需的行为是,当您单击列中的复选框时,它的行为与普通复选框一样,但如果在鼠标左键关闭时拖动复选框,则其选择状态将更改为与以前相反的状态。

到目前为止我尝试过的:

我尝试过子类化CheckBox和处理OnMouseEnter,但是单击的第一个复选框似乎捕获了鼠标,因此没有其他复选框触发OnMouseEnter事件。

我尝试实现一个拖放黑客,用户点击选择一个复选框,然后将该复选框拖到其他复选框上,以便其他人接收一个DragOver事件并切换状态。此解决方案使游标在拖放期间不超过另一个复选框时显示为带有斜杠的圆圈,这对于此应用程序是不可接受的。

我想要的:

我希望有一种方法来实现具有我描述的功能的复选框,最好是使用我可以重用的xaml样式或子类,因为这个功能需要在我的应用程序中的多个地方使用。

有一个优雅的方法来达到这个效果吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-03 05:35:42

我在我的应用程序中这样做,当您必须选择,比方说,30 checkBoxes时,非常方便。

为此,我亲自处理了预览鼠标事件: PreviewMouseLeftButtonDown、PreviewMouseMove、PreviewMouseLeftButtonUp。

在PreviewMouseLeftButtonDown中:我得到鼠标相对于控件的位置。

在PreviewMouseMove中:如果距离firstPoint足够远,我会从开始到当前位置绘制一个矩形。然后我在CheckBoxes中迭代,查看它们是否与矩形相交,如果是,则突出显示它们(这样用户就知道chexboxes将交换)。

在PreviewMouseLeftButtonUp中:我为交叉的CheckBoxes做交换。

如果它能帮助你,这是我使用的代码。它不是MVVM (:-),但是工作得很好,它可能会给您带来一些想法。它是vb.net代码的自动翻译。

要使其工作,您需要在CheckBoxes (例如,在相同的网格单元格内)之上设置一个画布,并带有属性IsHitTestVisible="False“。

在这个画布中,用适当的填充和笔画将一个矩形命名为"SelectionRectangle“,但不透明度为0.0。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// '' <summary>
// '' When Left Mouse button is pressed, remember where the mouse move start
// '' </summary>
private void EditedItems_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) {
    StartPoint = Mouse.GetPosition(this);
}

// '' <summary>
// '' When mouse move, update the highlight of the selected items.
// '' </summary>
private void EditedItems_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e) {
    if ((StartPoint == null)) {
        return;
    }
    PointWhereMouseIs = Mouse.GetPosition(this);
    Rect SelectedRect = new Rect(StartPoint, PointWhereMouseIs);
    if (((SelectedRect.Width < 20) 
                && (SelectedRect.Height < 20))) {
        return;
    }
    //  show the rectangle again
    Canvas.SetLeft(SelectionRectangle, Math.Min(StartPoint.X, PointWhereMouseIs.X));
    Canvas.SetTop(SelectionRectangle, Math.Min(StartPoint.Y, PointWhereMouseIs.Y));
    SelectionRectangle.Width = Math.Abs((PointWhereMouseIs.X - StartPoint.X));
    SelectionRectangle.Height = Math.Abs((PointWhereMouseIs.Y - StartPoint.Y));
    foreach (CheckBox ThisChkBox in EditedItems.Children) {
        object rectBounds = VisualTreeHelper.GetDescendantBounds(ThisChkBox);
        Vector vector = VisualTreeHelper.GetOffset(ThisChkBox);
        rectBounds.Offset(vector);
        if (rectBounds.IntersectsWith(SelectedRect)) {
            ((TextBlock)(ThisChkBox.Content)).Background = Brushes.LightGreen;
        }
        else {
            ((TextBlock)(ThisChkBox.Content)).Background = Brushes.Transparent;
        }
    }
}

// '' <summary>
// '' When Left Mouse button is released, change all CheckBoxes values. (Or do nothing if it is a small move -->
// '' click will be handled in a standard way.)
// '' </summary>
private void EditedItems_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e) {
    PointWhereMouseIs = Mouse.GetPosition(this);
    Rect SelectedRect = new Rect(StartPoint, PointWhereMouseIs);
    StartPoint = null;
    SelectionRectangle.Opacity = 0;
    //  hide the rectangle again
    if (((SelectedRect.Width < 20) 
                && (SelectedRect.Height < 20))) {
        return;
    }
    foreach (CheckBox ThisEditedItem in EditedItems.Children) {
        object rectBounds = VisualTreeHelper.GetDescendantBounds(ThisEditedItem);
        Vector vector = VisualTreeHelper.GetOffset(ThisEditedItem);
        rectBounds.Offset(vector);
        if (rectBounds.IntersectsWith(SelectedRect)) {
            ThisEditedItem.IsChecked = !ThisEditedItem.IsChecked;
        }
        ((TextBlock)(ThisEditedItem.Content)).Background = Brushes.Transparent;
    }
}

编辑:我在用户控件中使用了该代码。此控件以布尔值列表和字符串列表(标题)作为参数,并构建(使用WrapPanel)具有正确标题的CheckBoxes数组。因此,您可以使用矩形选择/取消选择,还有两个按钮来检查all/uncheck all。我还努力保持良好的列/行比,以处理7到200个布尔值的选择,并具有良好的列/行平衡。

票数 3
EN

Stack Overflow用户

发布于 2013-07-17 23:54:58

这个话题已经有了几个月的历史了,但我想我已经有了你们正在寻找的优雅的答案。

由于您将拖动和检查描述为两种不同的行为,所以首先设置数据处理程序.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
yourdatagrid.MouseDown += DragCheck_MouseDownHandler;

这将允许从数据化背景(但不是网格中的控件)开始拖动。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    private void DragCheck_MouseDownHandler(object sender, MouseEventArgs e)
    {
        if (e.Button != MouseButtons.Left) return;
        Control dgrid = sender as Control;
        foreach (CheckBox box in dgrid.Controls.OfType<CheckBox>())
        {
            box.Tag = null;
        }
        dgrid.MouseMove += DragMove_MouseMoveHandler;
    }

这将使用checkbox.Tag作为一个按钮,只在鼠标关闭时拖动一次。如果您将CheckBox标记用于其他方面,我相信您可以找到自己的方法来识别这些框。datagrid.MouseMove被设置为下一个处理程序..。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    private void DragMove_MouseMoveHandler(object sender, MouseEventArgs e)
    {
        Control dgrid = sender as Control;

        Point now = dgrid.PointToClient(Cursor.Position);
        if (e.Button == MouseButtons.Left)
        {
            Control under = dgrid.GetChildAtPoint(now);
            if (under != null && under.GetType() == typeof(CheckBox))
            {
                //if the point has a valid CheckBox control under it
                CheckBox box = under as CheckBox;
                if (box.Tag == null)// not yet been swiped
                {
                    box.Checked = !box.Checked;
                    box.Tag = true;
                }
            }
        }
        else
        {
            //if MouseButtons no longer registers as left
            //remove the handler 

            dgrid.MouseMove -= DragMove_MouseMoveHandler;

        }
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12708645

复制
相关文章
如何将HTML字符转换为DOM节点并动态添加到文档中
将字符串动态转换为DOM节点,在开发中经常遇到,尤其在模板引擎中更是不可或缺的技术。 字符串转换为DOM节点本身并不难,本篇文章主要涉及两个主题:<br />
用户1631416
2018/09/14
7.6K0
如何将HTML字符转换为DOM节点并动态添加到文档中
在 Debian 中如何将用户添加到 Sudoers
sudo是一个命令行工具,它允许被信任用户以另外一个用户身份运行命令,默认是 root 用户。
雪梦科技
2020/05/11
12.6K0
在 Debian 中如何将用户添加到 Sudoers
在 Ubuntu 中如何将用户添加到 Sudoers
sudo是一个命令行程序,它允许被信任的用户以 root 或者其他用户身份去运行命令。
雪梦科技
2020/05/09
34.4K0
在 Ubuntu 中如何将用户添加到 Sudoers
如何将MV中的音频添加到EasyNVR中做直播背景音乐?
EasyNVR已经支持自定义上传音频文件,可以做慢直播场景使用,前两天有一个开发者提出一个问题:想把一个MV中的音频拿出来放到EasyNVR中去做慢直播。
EasyNVR
2021/10/28
4.1K0
如何将MV中的音频添加到EasyNVR中做直播背景音乐?
Nexus高级配置之如何将本地jar添加到Nexus中
Java后端技术所推送文章,为本人原创、网上收集或其他作者投稿,对于网上收集部分除非确实无法确认,我们都会注明作者和来源。部分文章推送时未能与原作者取得联系。若涉及版权问题,烦请原作者联系我们,我们会在24小时内删除处理,谢谢!^_^ QQ:1573876303。
Java后端技术
2018/08/09
2.7K0
Nexus高级配置之如何将本地jar添加到Nexus中
IOS UITableViewCell 自定义高度动态调整 单元格 常用
//自定义单元格,单元格高度动态调整 1 import UIKit 2 3 class CustomizeUITableViewCell:UITableViewCell, UITableViewDataSource, UITableViewDelegate { 4 5 var tableView:UITableView!; 6 var comments:[String] = [] 7 8 override init(style:UITableViewCellStyle, reuseIde
用户5760343
2019/07/08
1K0
如何将WebRTC播放协议添加到EasyCVR?
自2020年浏览器的发展和兼容性发生了变化,WebRTC的延时性、安全性得到了提升和保护,尤其是疫情爆发后,实时视频的需求比之前增长了30倍,这更刺激了WebRTC产品的持续快速发展。因此我们也在EasyGBS、EasyDSS等平台内实现了WebRTC协议的播放。
TSINGSEE青犀视频
2021/11/23
1.4K0
在Oracle中,如何将一个数据库添加到CRS中?
虽然通过DBCA(DataBase Configuration Assistant,数据库配置助手)创建的数据库会自动加入CRS中,但通过RMAN创建的数据库是不会被加入CRS中的,在这种情况下就需要手动添加,将数据库加入CRS中后就可以通过srvctl来管理数据库了。
AiDBA宝典
2023/04/26
2.7K0
在Oracle中,如何将一个数据库添加到CRS中?
在 CentOS 上如何将用户添加到 Sudoers
sudo是一个命令行工具,它被设计为允许用户以其他用户(默认是 root 用户)身份去运行命令。
雪梦科技
2020/05/11
11.5K0
在 CentOS 上如何将用户添加到 Sudoers
VBA中动态数组的定义及创建
大家好,今日我们继续讲解VBA数组与字典解决方案的第19讲:动态数组的定义及创建。在VBA中,数组可分为固定数组和动态数组,也称为静态数组和动态数组。我们之前所定义的数组,都是静态数组。静态数组的特点是具有大小的数组。当我们事先知道数组的大小,我们可以直接声明为静态数组。固定数组定义方法:DIM 数组名(<下届>TO<上届>)。
用户8870853
2021/07/27
3.4K0
Maven项目中如何将自定义标签的tld文件添加到META-INF目录下
项目开发中为了提高复用性,经常把自定义标签打成单独的jar文件,同时将tld文件添加到jar文件中的META-INF目录下,这样其他的项目就能很方便的使用这些自定义标签。 tld文件中定义: 1 2 3 4 <tlib-version>1.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>demo</short-name> <uri>/demo-tags</uri> jsp中使用: 1 2
cloudskyme
2018/03/20
2.2K0
zabbix 5.0如何将esxi6.7添加到监控
今天有个需求,需要将一台esxi 6.7 server添加到我们的zabbix监控服务器上,将我做的操作踩的一点坑写出来
姚华
2022/06/29
1.8K0
zabbix 5.0如何将esxi6.7添加到监控
LeetCode 6016. Excel 表中某个范围内的单元格
Excel 表中的一个单元格 (r, c) 会以字符串 "<col><row>" 的形式进行表示,其中:
Michael阿明
2022/03/10
1.1K0
LeetCode 6016. Excel 表中某个范围内的单元格
问与答98:如何根据单元格中的值动态隐藏指定的行?
Q:我有一个工作表,在单元格B1中输入有数值,我想根据这个数值动态隐藏行2至行100。具体地说,就是在工作表中放置一个命令按钮,如果单元格B1中的数值是10时,当我单击这个命令按钮时,会显示前10行,即第2行至第11行;再次单击该按钮后,隐藏全部的行,即第2行至第100行;再单击该按钮,则又会显示第2行至第11行,又单击该按钮,隐藏第2行至第100行……也就是说,通过单击该按钮,重复显示第2行至第11行与隐藏第2行至第100行的操作。如图1所示。
fanjy
2021/03/12
6.4K0
Excel创建动态单元格区域
美术同学找我说想要一个查找引用功能,大体的表结构我看了一下有点奇怪(主要是命名一样),可能因为历史原因暂时也不太好修改,只好用Excel函数实现他所需要的功能。
meteoric
2022/09/08
1.6K0
Excel创建动态单元格区域
【已解决】UIView添加到KeyWindow上面自动会被 Release
?
君赏
2018/09/07
3660
如何将用户添加到Linux桌面【Linux-Command line】
我在 useradd command 上发布的文章阐述了对Linux系统用户管理的深层理解。Useradd 是一个命令行工具,但你也可以在Linux上通过图形方式管理用户。这就是本文主旨。
QRosie
2019/11/12
4.8K0
如何将用户添加到Linux桌面【Linux-Command line】
如何将Alexa添加到Raspberry Pi(或任何Linux设备)
我们的Amazon Alexa虚拟设备项目旨在提供将Alexa添加到任何Linux设备(包括Raspberry Pi板等嵌入式系统)的功能。
用户4122690
2020/03/14
1.5K0
如何将Alexa添加到Raspberry Pi(或任何Linux设备)
点击加载更多

相似问题

滚动条未在JTextArea中显示

12

Java Swing并发显示JTextArea

31

Java Swing JTextArea显示不正确

20

Java Swing JTextArea行号

20

JTextArea圆角Java Swing

13
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文