设为首页 收藏本站
查看: 1198|回复: 0

用Reactive响应式框架实现Windows phone 7 MVVM 按钮Command绑定,列表子元素的Command绑定

[复制链接]

尚未签到

发表于 2015-5-11 09:28:05 | 显示全部楼层 |阅读模式
1. Button 在WP7中似乎没有实现ICommand接口,为MVVM开发带来了一定的麻烦。 那么我怎么办呢? 而微软System.Windows.Interactivity.dll 中的EventTrigger似乎有问题,我不知道网上很多用这个MVVMLight 是怎么实现没有抱错的。。。。。

WP7,Silverlight开发会涉及到很多的线程问题,而一般的开发很难控制线程之间出错异常的捕捉,线程及资源的释放。Reactive (Rx) 似乎是这方面天生的料。 所以我项目用到了MVVM框架ReactiveUI。大家可以在https://github.com/xpaulbettsx/ReactiveUI 这里找到。闲话不多说了。 怎么做Button的命令绑定呢? 既然无路可走,那么我们就自己修路吧,实现ICommand的Button。上菜:



DSC0000.gif DSC0001.gif View Code


public class CommandButton : Button
    {
        #region Command Property
        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value); }
        }
        public static readonly DependencyProperty CommandProperty=
            DependencyProperty.Register("Command",
            typeof(ICommand),
            typeof(CommandButton),
            new PropertyMetadata(OnCommandChanged));
        private static void OnCommandChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            ((CommandButton)obj).OnCommandChanged(e);
        }
        private void OnCommandChanged(DependencyPropertyChangedEventArgs e)
        {
            if (e.OldValue != null)
            {
                ICommand command = e.OldValue as ICommand;
                if (command != null)
                {
                    command.CanExecuteChanged -= CommandCanExecuteChanged;
                }
            }
            if (e.NewValue != null)
            {
                ICommand command = e.NewValue as ICommand;
                if (command != null)
                {
                    command.CanExecuteChanged += CommandCanExecuteChanged;
                }
            }
            UpdateIsEnabled();
        }
        #endregion
        #region CommandParameter Property
        public object CommandParameter
        {
            get { return (object)GetValue(CommandParameterProperty); }
            set { SetValue(CommandParameterProperty, value); }
        }
        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.Register("CommandParameter",
            typeof(object),
            typeof(CommandButton),
            new PropertyMetadata(OnCommandParameterChanged));
        private static void OnCommandParameterChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            ((CommandButton)obj).UpdateIsEnabled();
        }
        #endregion

        private void CommandCanExecuteChanged(object sender, EventArgs e)
        {
            UpdateIsEnabled();
        }
        private void UpdateIsEnabled()
        {
            IsEnabled = Command != null ? Command.CanExecute(CommandParameter) : false;
        }
        protected override void OnClick()
        {
            base.OnClick();
            if (Command != null)
            {
                Command.Execute(CommandParameter);
            }
        }
    }

在给大家看看一个人员ViewModel 吧



View Code


///
    /// this view model include user information.
    ///
    public abstract class AccountViewModelBase : ViewModelBase
    {
        private string _UserId;
        ///
        /// User's account id
        ///
        public string UserId
        {
            get { return _UserId; }
            set { this.RaiseAndSetIfChanged(x => x.UserId, ref _UserId, value); }
        }
        //private User _CurrentUser;
        //protected ObservableAsPropertyHelper _CurrentUser;
        private User _user;
        public User CurrentUser
        {
            get
            {
                //if (_user != null)
                return _user;
                //return _CurrentUser.Value;
            }
            set { this.RaiseAndSetIfChanged(x => x.CurrentUser, ref _user, value); }
        }
        public ReactiveAsyncCommand GetUserCommand { get; private set; }
        public AccountViewModelBase(User user = null)
        {
            if (user != null)
            {
                _user = user;
                _UserId = user.Id;
            }
            GetUserCommand = new ReactiveAsyncCommand();
            this.ObservableForProperty(x => x.UserId)
                .Throttle(TimeSpan.FromMilliseconds(500))
                .Subscribe(x =>
                    {
                        _user = null;// if UserId change clear the loacl user.
                        GetUserCommand.Execute(x.Value);
                    });
           GetUserCommand.Subscribe(x =>
                OAuthHelper.CreateClient(OAuthHelper.USER_PROFILE_URL, new ParameterCollection { new Parameter("id", (string)x) })
                    .GetResponseText()
                    .Select(s => XElement.Parse(s))
                    .Select(xl => xl.ReadUserInfo())
                    .ObserveOn(RxApp.DeferredScheduler)
                    .Subscribe(
                        u => CurrentUser = u,
                        ex => { this.Log().Error(ex.ToString()); MessageBox.Show(ex.ToString()); }));
        }
    }
  


这里只要UserId 的值变化,就能重新查询获得新的CurrentUser对象。 而且UserId是根据500微妙中变化的最后一个值为准来查询。

上面我的ViewModel可以更具值变化来触发GetUserCommand命令,所有可以不用绑定, 若果需要在Xaml上来触发呢,看看XMAL文件只需要这么绑定就好



好了,时间差不多了,。。List列表的绑定需要用到RelativeSource Binding,Silverlight4 和 WP7都没有实现,

下一节我们再说说怎么自定义实现RelativeSource Binding吧休息。。。。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-65701-1-1.html 上篇帖子: Windows Phone 7的XNA游戏开发系列教程 下篇帖子: Windows phone 7 31 天学习笔记 30: 手势
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表