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

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。上菜:
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
/// <summary>
/// this view model include user information.
/// </summary>
public abstract class AccountViewModelBase : ViewModelBase
{
private string _UserId;
/// <summary>
/// User's account id
/// </summary>
public string UserId
{
get { return _UserId; }
set { this.RaiseAndSetIfChanged(x => x.UserId, ref _UserId, value); }
}

//private User _CurrentUser;
//protected ObservableAsPropertyHelper<User> _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文件只需要这么绑定就好
<my1:CommandButton Command="{Binding GoBackCommand}" x:Name="btnHome" Grid.Column="2"
Style="{StaticResource ButtonStyle}" Margin="0,0,1,0" />
好了,时间差不多了,。。List列表的绑定需要用到RelativeSource Binding,Silverlight4 和 WP7都没有实现,
下一节我们再说说怎么自定义实现RelativeSource Binding吧休息。。。。
posted @ 2011-05-18 15:49  木吉他-.-  阅读(901)  评论(0)    收藏  举报