icommand接口,Icommand接口
wpf mvvm模式 Icommand接口应该如何理解?
字面意思是:佛家讲究“养心”,行善积德,常保持心理平衡;道家讲究“ 养性”,道士修行的一种,静处一室,屏去左右,澄神静虑,也称入静。 修心修道只在理论中行进是没用的,只在寺院里修行也不可能获得更深层次的体会,只有在红尘中经历历练,经百折而不改初心,应千难而不悔才能磨砺一颗通透的心,
wpf如何知道数据源的更改是界面输入
wpf中界面中绑定了数据源后,数据在界面上的修改能反映到绑定源
View Code
3.2、命令绑定
在上面代码我们给按钮 Command 绑定了 Add Update Delete,接下来我们就开始实现功能
我们新建一个文件DelegateCommands.cs 实现接口ICommand
复制代码
public class DelegateCommands : ICommand
{
public Actionobject ExecuteCommand = null;
public Funcobject, bool CanExecuteCommand = null;
//当命令可执行状态发生改变时,应当被激发
public event EventHandler CanExecuteChanged;
//用于判断命令是否可以执行
public bool CanExecute(object parameter)
{
if (CanExecuteCommand != null)
{
return this.CanExecuteCommand(parameter);
}
else
{
return true;
}
}
//命令执行
public void Execute(object parameter)
{
if (this.ExecuteCommand != null) this.ExecuteCommand(parameter);
}
}
复制代码
回到ShowDataViewModel.cs 定义下面命令
复制代码
public DelegateCommands AddCommand { get; set; }
public DelegateCommands UpdateCommand { get; set; }
public DelegateCommands DeleteCommand { get; set; }
复制代码
把操作对应的方法写好
View Code
在进行绑定一下这样我们就能实现增删改了
复制代码
public ShowDataViewModel()
{
AddCommand = new DelegateCommands();
AddCommand.ExecuteCommand = new Actionobject(addStudent);
UpdateCommand = new DelegateCommands();
UpdateCommand.ExecuteCommand = new Actionobject(updateStudent);//修改方法
DeleteCommand = new DelegateCommands();
DeleteCommand.ExecuteCommand = new Actionobject(deleteStudent);//修改方法
mylist.Add(new User() { ID = 1, Name = "张三", Age = 20, Sex = "女", Remarks = "无" });
mylist.Add(new User() { ID = 2, Name = "李四", Age = 21, Sex = "女", Remarks = "无" });
mylist.Add(new User() { ID = 3, Name = "王五", Age = 22, Sex = "女", Remarks = "无" });
mylist.Add(new User() { ID = 4, Name = "赵六", Age = 24, Sex = "女", Remarks = "无" });
Binding();
}
复制代码
3.3、事件绑定
如果我们想点击控件里面的一行,下面对应的文本框就显示我们该怎么样呢?
回到View给DataGrid绑定事件 首先我们需要给项目添加引用:System.Windows.Interactivity 并且给页面引用命名空间
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
复制代码
DataGrid SelectionUnit="FullRow" AutoGenerateColumns="False" IsReadOnly="True" ItemsSource="{Binding ShowList,Mode=TwoWay}" x:Name="dataGrid" VerticalAlignment="Top" Height="182" HorizontalAlignment="Left" Width="408"
i:Interaction.Triggers
i:EventTrigger EventName="SelectionChanged"
i:InvokeCommandAction Command="{Binding SelectionChangedCommand}" CommandParameter="{Binding ElementName=dataGrid}" /
/i:EventTrigger
/i:Interaction.Triggers
DataGrid.Columns
DataGridTextColumn Binding="{Binding ID}" Header="编号"/
DataGridTextColumn Binding="{Binding Name}" Header="姓名" Width="100"/
DataGridTextColumn Binding="{Binding Age}" Header="年龄"/
DataGridTextColumn Binding="{Binding Sex}" Header="性别" Width="60"/
DataGridTextColumn Binding="{Binding Remarks}" Header="备注" Width="172"/
/DataGrid.Columns
/DataGrid
复制代码
我们在这里CommandParameter参数传的是控件dataGrid
然后我们去ViewModel ShowDataViewModel.cs
复制代码
public ICommand SelectionChangedCommand
{
get
{
return new DelegateCommandDataGrid((datagrid) =
{
if (datagrid.SelectedItems.Count 0)
{
user =(User)datagrid.SelectedItems[0];
ID = user.ID;
Name = user.Name;
Age = user.Age;
Sex = user.Sex;
Remarks = user.Remarks;
}
});
}
}
复制代码
上一步 需添加引用 Microsoft.Practices.Prism.dll 这样就完成了
这样一个小案例就完成了。
wpf 怎么调用icommand接口
表示弱引用,即在引用对象的同时仍然允许垃圾回收来回收该对象。
如果应用程序的代码可以访问一个正由该程序使用的对象,垃圾回收器就不能收集该对象,那么,就认为应用程序对该对象具有强引用。
弱引用允许应用程序访问对象,同时也允许垃圾回收器收集相应的对象。如果不存在强引用,则弱引用的有限期只限于收集对象前的一个不确定的时间段。使用弱引用时,应用程序仍可对该对象进行强引用,这样做可防止该对象被收集。但始终存在这样的风险:垃圾回收器在重新建立强引用之前先处理该对象。
弱引用特别适合以下对象:占用大量内存,但通过垃圾回收功能回收以后很容易重新创建。
假设 Windows 窗体应用程序中的一个树视图向用户显示了复杂的选项层次结构。如果基础数据量很大,则用户使用应用程序中的其他部分时,在内存中保留该树会导致效率低下。
当用户切换到应用程序的其他部分时,可使用 WeakReference 类来创建对该树的弱引用,并销毁所有强引用。当用户切换回该树时,应用程序会尝试获得对该树的强引用,如果得到,就不必重新构造该树。
要对某个对象建立弱引用,请使用要跟踪的对象的实例创建一个 WeakReference。然后将 Target 属性设置为该对象,将该对象设置为 null。
可创建短弱引用或长弱引用:
短
垃圾回收功能回收对象后,短弱引用的目标会变为 null。弱引用本身是托管对象,和任何其他托管对象一样需要经过垃圾回收。短弱引用是 WeakReference 的默认构造函数。
长
调用对象的 Finalize 方法后,会保留长弱引用。这样,您就可以重新创建该对象,但该对象仍保持不可预知的状态。要使用长引用,请在 WeakReference 构造函数中指定 true。
如果对象的类型没有 Finalize 方法,则会应用短弱引用功能,该弱引用只在目标被收集之前有效,运行终结器之后可以随时收集目标。
要建立强引用并重新使用该对象,请将 WeakReference 的 Target 属性强制转换为该对象的类型。如果 Target 属性返回 null,则表示对象已被收集;否则,您可继续使用该对象,因为应用程序已重新获得了对它的强引用。
这是摘自MSDN的解释,那么简单来说,弱引用与强引用的区别在于,它允许GC回收。
ICommand实现:
在WPF进阶之接口(3):INotifyPropertyChanged,ICommand我们看到在ICommand的实现代码中:
internal class CommandManagerHelper
{
internal static void CallWeakReferenceHandlers(ListWeakReference handlers)
{
if (handlers != null)
{
// Take a snapshot of the handlers before we call out to them since the handlers
// could cause the array to me modified while we are reading it.
EventHandler[] callees = new EventHandler[handlers.Count];
int count = 0;
for (int i = handlers.Count - 1; i = 0; i--)
{
WeakReference reference = handlers[i];
EventHandler handler = reference.Target as EventHandler;
if (handler == null)
{
// Clean up old handlers that have been collected
handlers.RemoveAt(i);
}
else
{
callees[count] = handler;
count++;
}
}
// Call the handlers that we snapshotted
for (int i = 0; i count; i++)
{
EventHandler handler = callees[i];
handler(null, EventArgs.Empty);
}
}
}
internal static void AddHandlersToRequerySuggested(ListWeakReference handlers)
{
if (handlers != null)
{
foreach (WeakReference handlerRef in handlers)
{
EventHandler handler = handlerRef.Target as EventHandler;
if (handler != null)
{
CommandManager.RequerySuggested += handler;
}
}
}
}
internal static void RemoveHandlersFromRequerySuggested(ListWeakReference handlers)
{
if (handlers != null)
{
foreach (WeakReference handlerRef in handlers)
{
EventHandler handler = handlerRef.Target as EventHandler;
if (handler != null)
{
CommandManager.RequerySuggested -= handler;
}
}
}
}
internal static void AddWeakReferenceHandler(ref ListWeakReference handlers, EventHandler handler)
{
AddWeakReferenceHandler(ref handlers, handler, -1);
}
internal static void AddWeakReferenceHandler(ref ListWeakReference handlers, EventHandler handler, int defaultListSize)
{
if (handlers == null)
{
handlers = (defaultListSize 0 ? new ListWeakReference(defaultListSize) : new ListWeakReference());
}
handlers.Add(new WeakReference(handler));
}
internal static void RemoveWeakReferenceHandler(ListWeakReference handlers, EventHandler handler)
{
if (handlers != null)
{
for (int i = handlers.Count - 1; i = 0; i--)
{
WeakReference reference = handlers[i];
EventHandler existingHandler = reference.Target as EventHandler;
if ((existingHandler == null) || (existingHandler == handler))
{
// Clean up old handlers that have been collected
// in addition to the handler that is to be removed.
handlers.RemoveAt(i);
}
}
}
}
}
CommandManagerHelper类主要是对将事件用WealReference的形式实现,Add和Remove。为什么要这样处理呢,在C#中的弱事件(Weak Events in C#)我们谈到了,虽然C#在实现事件订阅机制的时候是线程安全的,但在用户的使用过程中仍然可能导致事件的handler不能同步,即一个线程可能已经将事件注销了,而另一个线程可能仍然要触发事件,那时系统就会抛出 NullReferenceException而导致系统崩溃。原因请详细阅读C#中的弱事件(Weak Events in C#)一文。
可以看到我们在实现事件的订阅机制的时候,必须要考虑到上述问题。上一章节ICommand实现正是采用了Solution2(弱引用)来解决此问题。即每次添加、删除和触发事件之前,必须检查WeakReference的List,查看是否已经存在,或是已经被GC回收,相应采取处理。
这样与MVVM相关的几个基本的Inerface,我已经陆续向大家介绍完毕。下一节,将向大家详细介绍控件的重写,可能在此过程中仍然要涉及几个接口(IList,IEnuerator,ICollection等),但是这些Interface主要是与控件重写技术相关的,我将放入相应章节中做出解释。
wpf 怎么刷新 icommand 的状态
基础类,继承与ICommand接口
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Windows.Input;
6
7 namespace WpfExample
8 {
9 public class RelayCommand : ICommand
10 {
11 #region Fields
12
13 /// summary
14 /// Encapsulated the execute action
15 /// /summary
16 private Actionobject execute;
17
18 /// summary
19 /// Encapsulated the representation for the validation of the execute method
20 /// /summary
21 private Predicateobject canExecute;
.NET开发,自己学的,下面的代码理解不了了,能帮我逐行写个注释吗?应该如何理解这段代码
逐行注释就算了……
在学 WPF 吗?
这就是在写 ICommand 接口的实现,建议F12进去看看,需要实现哪些方法。
简单解释一下,你这个类里面有两个属性(对外暴露,用于用户赋值操作):
public Actionobject ExcuteAction?{ get; set; }
设置一个 Actionobject 委托方法,就是说你这个 Command 到底是干嘛的
public Funcbool CanExecuteFunc { get; set; }
设置一个 Funcbool 委托方法,用于判断什么时候允许执行 上面的 Actionobject,
即,什么时候你可以允许执行这个Command
相关文档:
Action
FuncTResult
成员访问运算符和表达式 里面介绍了 ?. 这种空条件运算符,好像C# 6.0 添加的
现在很多MVVM框架里面,都有现成的 ICommand实现,基本也不用自己动手写