在WPF中的ItemsControl中使用事件和命令(Using events and Commands within ItemsControl in WPF)
Say I have a standard WPF ItemsControl bound to an ObservableCollection of "Dog" objects like so:
<ItemsControl ItemsSource="{Binding Dogs}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Breed}"/>
<TextBlock Text="{Binding Weight}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I want the user to be able delete any of the dogs in the collection. In the past I've been doing this with a ListBox control and binding my ViewModel to the SelectedItem property. I then create a button with an event that removes the selected object from the ObservableCollection.
This works OK but I'd like to lay it out so each row can have its own delete button.
<ItemsControl ItemsSource="{Binding Dogs}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Breed}"/>
<TextBlock Text="{Binding Weight}"/>
<Button Click="Click_EventHandler"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
And an event that looks like this:
private void ListBox_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//Delete this Dog Object from Observable Collection
}
Shoving a button into the ItemTemplate and giving it an event crashes WPF, and binding a command to a button within an ItemTemplate doesn't do anything at all so my former method will not work.
The only way I can think of doing this is adding a ToggleButton to the ItemTemplate and binding to the View Model, and then firing an event in the Setter. Not exactly an elegant solution.
Anyone have any better idea on how to go about this?
You can bind commands like everything else, but first you need your implementation of ICommand interface, something like this:
public class RelayCommand: ICommand
{
private Action<object> _execute;
private Predicate<object> _canExecute; public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
} public RelayCommand(Action<object> execute) : this(execute, null) { } public event EventHandler CanExecuteChanged; public bool CanExecute(object parameter)
{
return _canExecute != null ? _canExecute(parameter) : true;
} public void Execute(object parameter)
{
if (CanExecute(parameter) && _execute != null) _execute(parameter);
}
}
and then your Dog class needs to expose for example ICommand DeleteCmd property:
class Dog
{
...
private RelayCommand _deleteCmd; private void DoDelete(object parameter)
{
//put delete action here
} public ICommand DeleteCmd
{
get
{
if (_deleteCmd == null) _deleteCmd = new RelayCommand(o => DoDelete(o));
return _deleteCmd;
}
}
}
and then you bind it like this:
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Breed}"/>
<TextBlock Text="{Binding Weight}"/>
<Button Command="{Binding DeleteCmd}"/>
</StackPanel>
说我有一个标准的WPF ItemsControl绑定到一个ObservableCollection的"狗"对象像这样:
< ItemsControl ItemsSource ="{绑定狗}">
< ItemsControl.ItemTemplate>
< DataTemplate>
< StackPanel Orientation ="Horizontal">
< TextBlock Text ="{Binding Name}"/>
< TextBlock Text ="{Binding Breed}"/>
< TextBlock Text ="{Binding Weight}"/>
< / StackPanel>
< / DataTemplate>
< /ItemsControl.ItemTemplate>
< / ItemsControl>
我希望用户能够删除集合中的任何狗。过去我一直在使用ListBox控件,并将ViewModel绑定到SelectedItem属性。然后,我创建一个带有事件的按钮,从ObservableCollection中删除所选对象。
这样可以正常工作,但是我想排除它,所以每一行都可以自己的删除按钮。
< ItemsControl ItemsSource ="{Binding Dogs}">
< ItemsControl.ItemTemplate>
< DataTemplate>
< StackPanel Orientation ="Horizontal">
< TextBlock Text ="{Binding Name}"/>
< TextBlock Text ="{Binding Breed}"/>
< TextBlock Text ="{Binding Weight}"/>
< Button Click ="Click_EventHandler"/>
< / StackPanel>
< / DataTemplate>
< /ItemsControl.ItemTemplate>
< / ItemsControl>
另外一个类似这样的事件:
< pre> private void ListBox_PreviewMouseDown(object sender,System.Windows.Input.MouseButtonEventArgs e)
{
//从可观察集合中删除此Dog对象
}
将一个按钮放入ItemTemplate并给它一个事件崩溃WPF,并将命令绑定到一个按钮在ItemTemplate中没有任何东西,所以我以前的方法将无法正常工作。
我可以想到这样做的唯一方法是将一个ToggleButton添加到ItemTemplate,绑定到视图模型,然后在Setter中触发一个事件。不完全是一个优雅的解决方案。
任何人都有更好的想法如何去做这个?
您可以像其他一样绑定命令,但首先需要实现 ICommand 界面,如下所示:
public class RelayCommand:ICommand
{
private Action< object> _执行;
private Predicate< object> _canExecute;
public RelayCommand(Action< object> execute,Predicate< object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public RelayCommand(Action< object> execute):this(execute,null){}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return _canExecute!= null? _canExecute(参数):true;
}
public void Execute(object parameter)
{
if(CanExecute(parameter)&& _execute!= null)_execute(parameter)
}
}
然后您的 / code>类需要公开,例如 ICommand DeleteCmd 属性:
class Dog
{
...
private RelayCommand _deleteCmd;
private void DoDelete(object parameter)
{
// put delete action here
}
public ICommand DeleteCmd
{
get
{
if(_deleteCmd == null)_deleteCmd = new RelayCommand(o => DoDelete(o));
return _deleteCmd;
}
}
}
然后你绑定它这个:
< StackPanel Orientation ="Horizontal">
< TextBlock Text ="{Binding Name}"/>
< TextBlock Text ="{Binding Breed}"/>
< TextBlock Text ="{Binding Weight}"/>
< Button Command ="{Binding DeleteCmd}"/>
< / StackPanel>
在WPF中的ItemsControl中使用事件和命令(Using events and Commands within ItemsControl in WPF)的更多相关文章
- WPF使用MVVM(三)-事件转命令
WPF使用MVVM(三)-事件转命令 上一节介绍了WPF中的命令,可是仅仅介绍的是WPF框架给我们提供的点击命令,也就是用Command属性来绑定一个命令,用来响应按钮的点击行为!显然这是不够的,界面 ...
- WPF: 在 MVVM 设计中实现对 ListViewItem 双击事件的响应
ListView 控件最常用的事件是 SelectionChanged:如果采用 MVVM 模式来设计 WPF 应用,通常,我们可以使用行为(如 InvokeCommandAction)并结合命令来实 ...
- 【转】【WPF】WPF中的Button的MouseDown事件不触发问题
按照WPF的帮助说明,某些控件的路由事件被内部处理了,已经被标记为Handled,自行定义的事件处理代码便不再起作用了,有时候会很郁闷! 不过WPF提供了必要的方法. 1)使用相应的Preview事件 ...
- WPF老矣,尚能饭否——且说说WPF今生未来(中):策略
本文接上文<WPF老矣,尚能饭否——且说说WPF今生未来(上):担心>继续. “上篇”中部分精彩的点评: 虽然WPF不再更新了,但是基于WPF的技术还是在发展着,就比如现在的WinRT,只 ...
- WPF中嵌入WinForm中的webbrowser控件
原文:WPF中嵌入WinForm中的webbrowser控件 使用VS2008创建WPF应用程序,需使用webbrowser.从工具箱中添加WPF组件中的webbrowser发现其中有很多属性事件不能 ...
- WPF编程,C#中对话框自动关闭的一种方法。
原文:WPF编程,C#中对话框自动关闭的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details/8 ...
- 继续聊WPF——如何获取ListView中选中的项
在WPF中获Listview中选中的项,与WinForm里面有着很大的区别,要亲身去研究一下在WPF中如果处理,其实也不难,来,下面我们一起来通过一个简单的示例来感悟一下吧. 第一步就是建立一个WPF ...
- WPF实用指南一:在WPF窗体的边框中添加搜索框和按钮
原文:WPF实用指南一:在WPF窗体的边框中添加搜索框和按钮 在边框中加入一些元素,在应用程序的界面设计中,已经开始流行起来.特别是在浏览器(Crome,IE,Firefox,Opera)中都有应用. ...
- javascript中通过匿名函数进行事件绑定
随机推荐
- echarts堆叠柱状图在最上面的柱子显示总和
需求 柱子需设置barMinHeight 在堆叠柱状图的最上面显示当前堆叠的总和 直接上代码吧 需要注意:设置barMinHeight时为了让0不显示,只能将0设置为null; 设置为null的柱子l ...
- MQTT 1——物联网集成项目技术选型与说明
最近做的JAVA项目与物联网设备有集成,记录一下从技术选型到实现,整合: 1.通信协议技术选型,MQTT技术介绍2.MQTT服务端安装,客户端测试3.MQTT客户端与Spring MVC整合 1.项目 ...
- 【LeetCode】137. 只出现一次的数字 II(剑指offer 56-II)
137. 只出现一次的数字 II(剑指offer 56-II) 知识点:哈希表:位运算 题目描述 给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 .请你找出并返回 ...
- Spring总结之SpringMvc上
一.简介 Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架. 二.流程架构 1.用户发送请求至 前端控制器DispatcherServlet ...
- Spark—初识spark
Spark--初识spark 一.Spark背景 1)MapReduce局限性 <1>仅支持Map和Reduce两种操作,提供给用户的只有这两种操作 <2>处理效率低效 Map ...
- VM虚拟机桥接模式无法联网、NAT模式能正常联网
桥接模式:使虚拟机客户机可以和主机在同一网段,这样,和主机同局域网内的其他主机就也可以ping到虚拟机了: 因此,虚拟机设置为桥接模式,这样以后就可以方便的使用虚拟机了: 有时,虚拟机为桥接模式上不了 ...
- django中路由配置的正则
在django中配置路由遇到正则的坑: django2.x版本中使用re_path来进行正则表达式的匹配 用法如下: from Django.urls import re.path(导入re_path ...
- 构建后端第5篇之---Idea 查看继承 实现关系图
first question: how to show a class children class : move mousrmark to class name , Ctrl + H how t ...
- 为什么大家都在用WebRTC?
WebRTC代表网络实时通信.它是一种非常令人兴奋,强大且具有高度破坏性的尖端技术和标准.自从WebRTC诞生以来,80%的浏览器都开始支持它.有数据显示,2017年~2021年期间,WebRTC市场 ...
- Spring Cloud分区发布实践(3) 网关和负载均衡
注意: 因为涉及到配置测试切换, 中间环节需按此文章操作体验, 代码仓库里面的只有最后一步的代码 准备好了微服务, 那我们就来看看网关+负载均衡如何一起工作 新建一个模块hello-gateway, ...