• [译]5步实现Silverlight中的Command


    在这里我打算分享一个十分轻量级的技巧实现Silverlight4中的Command。

    Step 1 – 实现ICommand接口

    第一步是新建一个类来管理Command相关的逻辑,它需要实现ICommand接口。当然,还有很多其他的方式,我在这里只介绍这种简单有效的实现。

    DelegatedCommand类实现了ICommand接口定义的CanExecute、Execute方法和CanExecuteChanged事件。

    public class DelegateCommand : ICommand {
        Func<object, bool> canExecute;
        Action<object> executeAction;
        bool canExecuteCache;
        public DelegateCommand(Action<object> executeAction, Func<object, bool> canExecute) {
            this.executeAction = executeAction;
            this.canExecute = canExecute;
        }
    
        #region ICommand 成员
        public bool CanExecute(object parameter) {
            bool temp = canExecute(parameter);
            if (canExecuteCache != temp) {
                canExecuteCache = temp;
                if (CanExecuteChanged != null) {
                    CanExecuteChanged(this, new EventArgs());
                }
            }
            return canExecuteCache;
        }
    
        public event EventHandler CanExecuteChanged;
        public void Execute(object parameter) {
            executeAction(parameter);
        }
        #endregion
    }
    
    

    Step 2 – 定义Command

    在你的ViewModel中增加一个公共属性对外提供ICommand。一般来说,这个属性会绑定到界面的按钮上。

    public ICommand LoadProductsCommand { get; set; }

    Step 3 – 创建Command

    在你的ViewModel的构造函数中通过第一步中创建的DelegateCommand类实例化LoadProductsCommand。

    LoadProductsCommand = new DelegateCommand(LoadProducts, CanLoadProducts);

    Step 4 – 创建ViewModel

    接下来你需要确认你的View可以和你的ViewModel通信。很多方式都可以实现这一点,这里我是将ViewModel在XAML中定义为一个静态资源。

    <UserControl.Resources>
        <local:ProductViewModel x:Key="vm"/>
    </UserControl.Resources>

    Step 5 – 绑定到Command

    向UI中添加一个按钮然后将你ViewModel中创建的Command属性绑定到这个按钮上。接下来你可能需要通过设置绑定中的CommandParameter向Command传递参数,这里可以是一个UI元素,如TextBox。

    <Button Content="Load" Width="120"    
            Command="{Binding LoadProductsCommand}"    
            CommandParameter="{Binding ElementName=FilterTextBox, Path=Text}" />

    就此5步,你的应用程序已经实现Command了。

    附录 …

    ProductViewModel的全部代码:

    public class ProductViewModel : ViewModelBase {
        public ProductViewModel() {
            this.Products = new ObservableCollection<Product>();
            // 注意: 这里只是代码示例   
            // ViewModel中不应为Model定义数据:-)   
            // 我们可以通过调用服务得到Model所需数据. 
            this.AllProducts = new ObservableCollection<Product>();
            this.AllProducts.Add(new Product { ProductId = 1, ProductName = "Apple" });
            this.AllProducts.Add(new Product { ProductId = 2, ProductName = "Orange" });
            this.AllProducts.Add(new Product { ProductId = 3, ProductName = "Banana" });
            this.AllProducts.Add(new Product { ProductId = 4, ProductName = "Pear" });
            this.AllProducts.Add(new Product { ProductId = 5, ProductName = "Grape" });
            this.AllProducts.Add(new Product { ProductId = 6, ProductName = "Grapefruit" });
            this.AllProducts.Add(new Product { ProductId = 7, ProductName = "Strawberry" });
            this.AllProducts.Add(new Product { ProductId = 8, ProductName = "Melon" });
            this.AllProducts.Add(new Product { ProductId = 9, ProductName = "Guava" });
            this.AllProducts.Add(new Product { ProductId = 10, ProductName = "Kiwi" });
            this.AllProducts.Add(new Product { ProductId = 11, ProductName = "Pineapple" });
            this.AllProducts.Add(new Product { ProductId = 12, ProductName = "Mango" });
            LoadProductsCommand = new DelegateCommand(LoadProducts, CanLoadProducts);
        }
        private void LoadProducts(object param) {
            string filter = param as string ?? string.Empty;
            this.Products.Clear();
            var query = from p in this.AllProducts
                        where p.ProductName.ToLower().StartsWith(filter.ToLower())
                        select p;
            foreach (var item in query) {
                this.Products.Add(item);
            }
        }
        private bool CanLoadProducts(object param) {
            return true;
        }
        public ICommand LoadProductsCommand { get; set; }
        public ObservableCollection<Product> AllProducts { get; set; }
        private ObservableCollection<Product> products;
        public ObservableCollection<Product> Products {
            get {
                return products;
            }
            set {
                products = value;
                this.FirePropertyChanged("Product");
            }
        }
    }
    接下来是ViewModelBase类的全部代码,很简单的一个类,主要用来辅助包装PropertyChanged。
    我项目中的所有ViewModel都继承了这个类。
    public abstract class ViewModelBase : INotifyPropertyChanged {
        public ViewModelBase() {
        }
        public event PropertyChangedEventHandler PropertyChanged;
        protected void FirePropertyChanged(string propertyname) {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyname));
        }
    }
  • 相关阅读:
    asp.net core mvc 之 DynamicApi
    打造适用于c#的feign
    asp.net App_Code文件夹相关操作
    基于Mono.Cecil的静态注入
    补充ICache
    自制简单实用IoC
    自制简单的.Net ORM框架 (一) 简介
    解决Asp.net Mvc中使用异步的时候HttpContext.Current为null的方法
    微信开发之.Net
    VS2017 网站打包发布生成的文件中包含.pdb文件,解决办法
  • 原文地址:https://www.cnblogs.com/024hi/p/1671683.html
Copyright © 2020-2023  润新知