Windows Phone 7 的 MixModes Synergy Toolkit






4.56/5 (3投票s)
介绍 Synergy Toolkit for Windows Phone 7 版本 1.0 的功能
引言
Synergy 是一个平台工具包,可释放 WPF、Silverlight 和 Windows Phone 7 平台的强大功能。在本博文中,我将讨论该库的 Windows 7 手机部分,以及它如何帮助将开发实践某种程度上统一到 WPF 的方式,并利用数据绑定功能。
可以在其 CodePlex 主页访问 Synergy 工具包,在那里,圣诞老人(我)每天都会带来新的礼物和愿望。我已在 下载区发布了 Windows Phone 7 库的 v1 版本。
有关 WPF Synergy Toolkit 的背景信息,您可以参阅我之前的博客 此处。我还为 Synergy 的 WPF 版本编写了一个停靠窗口框架,您可以参阅 此处,以及一篇关于窗口主题的文章 此处。
您可以在 Twitter 上关注我 @ashishkaila。
言归正传,让我带您了解 v1 版本的功能。
Windows Phone 7 开发的基础框架
命令支持
CommandBase
类为自定义命令提供了灵活的实现。此类使用 Action<object>
实例进行命令调用,并使用可选的 Predicate<object>
进行命令执行评估。如果未指定谓词,则假定命令可以随时执行。简单来说,可以使用以下方式实例化 CommandBase
类:
CommandBase myCommand = new CommandBase(arg=>Foo(arg), arg=>CanFoo(arg));
此外,WP7 和 Silverlight 默认不提供绑定的能力。
依赖系统增强
依赖系统提供了一些增强功能,可帮助开发人员轻松利用该框架进行与绑定和依赖属性相关的更高级操作。这些增强功能如下:
可观察绑定
顾名思义,ObservableBinding
类会观察绑定以进行值更改,并提供绑定的最新值。此类在自定义行为和触发器操作中非常有用,在这些操作中,关联对象的数据上下文不会传播到这些实体。这是因为行为和触发器是 static
Interaction 类(在 System.Windows.Interactivity
程序集中声明)中的附加属性,因此与依赖系统分离。
通过声明一个类型为 Binding
的依赖属性,并在 Behavior
/TriggerAction
中使用 ObservableBinding
,您可以同时挂钩到关联对象的依赖属性系统,以及评估绑定的最新值。
例如,EventToCommand
触发器操作定义了一个类型为 Binding
的依赖属性 Command
:
public static DependencyProperty CommandProperty =
DependencyProperty.Register("Command",
typeof (Binding),
typeof (EventToCommand),
new PropertyMetadata(null, OnCommandChanged));
它还声明了命令的 ObservableBinding
:
private readonly ObservableBinding _observableCommandBinding = new ObservableBinding();
此 _observableCommandBinding
成员将为我们提供 Command
属性公开的 Binding
的最新值。
有一些规则可确保 ObservableBinding
对 Binding
属性按预期工作。基本上,每当 Binding
属性发生更改时,我们都必须从旧的 Binding
中取消挂钩,并挂钩到新的 binding
。这在 OnCommandChanged
方法中完成,该方法在 Binding
属性更改时被调用(即实际的 Binding
属性,而不是 Binding
的值)。
private static void OnCommandParameterChanged
(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
EventToCommand eventToCommand = d as EventToCommand;
if (eventToCommand == null)
{
return;
}
eventToCommand._observableCommandParameterBinding.Detach();
if ((e.NewValue != null) && (eventToCommand.AssociatedObject != null))
{
eventToCommand._observableCommandParameterBinding.Attach
(eventToCommand.Command eventToCommand.AssociatedObject);
}
}
另外,当关联对象最初附加到 TriggerAction
/ Behavior
时,我们需要附加到 ObservableBinding
:
protected override void OnAttached()
{
base.OnAttached();
if (Command != null)
{
_observableCommandBinding.Attach(Command, AssociatedObject);
}
}
如果跳过以上步骤,ObservableBinding
将不会跟踪 Binding
的初始值。
可观察依赖属性
另一方面,ObservableDependencyProperty
通过事件通知提供了跟踪另一个 DependencyObject
中声明的依赖属性更改的能力。ObservableDependencyProperty
的构造函数接受两个参数:一个表示要观察的依赖属性名称的 string
,以及一个将在依赖属性更改时调用的 DependencyPropertyChangedEventHandler
类型委托。
ObservableDependencyProperty _verticalScrollChange =
new ObservableDependencyProperty("VerticalOffset", OnVerticalScroll);
要跟踪实际 DependencyObject
的依赖属性更改,必须通过 AddValueChanged
方法将 ObservableDependencyProperty
实例附加到它。
_verticalScrollChange.AddValueChanged(_scrollViewer);
同样,要分离或停止属性更改跟踪,可以调用 RemoveValueChanged
方法。
_verticalScrollChange.RemoveValueChanged();
完整的 MVVM 框架
通过继承基类 ViewModelBase
,即可实现自定义视图模型。要引发 PropertyChanged
事件,可以调用类型安全的 RaisePropertyChanged
方法,并传入包含属性引用的表达式,例如:
RaisePropertyChanged(x=>MyProperty);
ViewModelBase
还包含一个 Navigate
方法,可以导航手机到绑定的视图,并在后台执行数据绑定(更多内容将在下一节介绍),例如:
MyViewModel viewModel = new MyViewModel();
viewModel.Navigate(); // Note: For this to work,
// your application must inherit from PhoneApplication class (see below)
通过声明性的视图-视图模型绑定简化导航
在 WPF 中,DataTemplates
可以在应用程序级别将 ViewModel
绑定到 View
。此绑定使得在 ContentPresenter
内可以运行时生成视图。我希望将相同的想法扩展到 Windows Phone 7 屏幕导航,因为应用程序内的基于 URL 的导航似乎容易出错,并且传递查询参数很麻烦。
ViewSelector
类提供了与 ViewBinding
类结合使用的声明性绑定功能。基本上,您可以在应用程序资源中定义此映射:
<Framework:ViewSelector x:Key="ApplicationViewSelector">
<Framework:ViewBinding ViewModelType="INameU.ViewModels.NameListViewModel"
ViewUri="/Views/NameListView.xaml" />
<Framework:ViewBinding ViewModelType="INameU.ViewModels.NameDetailViewModel"
ViewUri="/Views/NameDetailView.xaml" />
</Framework:ViewSelector>
其中,Framework
被映射为:
xmlns:Framework="clr-namespace:MixModes.Phone.Synergy.Framework;
assembly=MixModes.Phone.Synergy"
完成此操作后,您可以从 ViewModel
实例调用 Navigate
方法,导航到映射的视图,同时进行数据绑定,而无需使用任何 URL!
DockPanel 和 WrapPanel 控件
我已将 Silverlight Toolkit for Windows Phone 7 中的 DockPanel
和 WrapPanel
移植过来,因此如果您除了这些面板之外不使用任何其他附加功能,则无需引用该工具包。
EventToCommand 触发器操作
一个常见的痛点是,诸如 But
ton 和 ListBoxItem
等控件缺少 Command
和 CommandParameter
属性。为了填补这一空白,可以使用 EventToCommand
触发器操作将 RoutedEvent
映射到 ICommand
实例以及 CommandParameter
实例。要将 RoutedCommand
绑定到 EventToCommand
触发器,您需要将触发器添加到关联的框架元素:
<Button Content="Click Me">
<Custom:Interaction.Triggers>
<Custom:EventTrigger EventName="Click">
<Triggers:EventToCommand Command=
"{Binding Path=DataContext.ShowDetailsCommand, ElementName=Page}"
PassEventArgsToCommand="True"/>
</Custom:EventTrigger>
</Custom:Interaction.Triggers>
</Button>
当 PassEventArgsToCommand
属性设置为 true
时,会将 RoutedEventArgs
作为 CommandParameter
传递给关联 ICommand
的 Execute
方法。
ScrollLoadBehavior
ScrollLoadBehavior
允许用户垂直滚动到滚动查看器的底部时异步加载数据。ScrollLoadBehavior
有一个关联的 ICommand
和 CommandParameter
,在滚动查看器到达最底部时随时执行。加载通过 ICommand
的 CanExecute
方法检测。例如:
<ListBox DataContext="{Binding}"
ItemsSource="{Binding Path=Names}">
<Custom:Interaction.Behaviors>
<Behavior:ScrollLoadBehavior Command="{Binding Path=LoadNamesCommand}" />
</Custom:Interaction.Behaviors>
</ListBox>
请注意 ListBox
中显式的 DataContext=”{Binding}”
。这是必需的,因为如果没有显式的父数据绑定,ItemsSource
会将 DataContext
设置为其值,从而导致 ScrollLoadBehavior
的绑定失败。
开箱即用的转换器
工具包中提供了许多常用的开箱即用转换器:
EnumMatchConverter
– 匹配枚举成员的值与常量值,并返回一个布尔值指示是否匹配。例如,如果您想在状态为StateEnum.IsError
时启用控件,可以执行以下操作:Enabled="{Binding Path=State, Converter={StaticResource EnumConverter}, ConverterParameter=IsError}"
NotConverter
– 反转布尔表达式的值。VisibilityConverter
– 根据布尔值,显示(如果值为true
)或折叠(如果值为false
)控件的可见性。PipeConverter
– 将一个值通过多个转换器进行传递,以计算绑定表达式的最终值。例如,如果您想匹配一个值到一个枚举成员“Loading
”,然后确定控件的可见性,可以如下声明一个管道转换器:<conv:PipeConverter x:Key="LoadingMessageVisibilityConverter"> <conv:EnumMatchConverter /> <conv:VisibilityConverter /> </conv:PipeConverter>
值从上到下进行传递,因此首先调用
EnumMatchConverter
,然后调用VisibilityConverter
。要使用它,只需如下引用PipeConverter
:Visibility="{Binding Path=State, Converter={StaticResource LoadingMessageVisibilityConverter}, ConverterParameter=Loading}"
ThemeBasedResourceConverter
– 此转换器根据 Windows 7 Phone 的主题(暗色或亮色)返回资源。要使用此转换器,需要通过LightThemeResource
和DarkThemeResource
属性指向两个主题的资源。例如,如果您的应用程序具有两种主题的导航按钮图像,如 NavigationLight.png 和 NavigationDark.png,您可以使用ThemeBasedResourceConverter
将适当的图像设置为按钮的背景,如下所示:<phone:PhoneApplicationPage.Resources> <Converters:ThemeBasedResourceConverter x:Key="ThemeBasedResourceConverter" LightThemeResource="../Resources/NavigationLight.png" DarkThemeResource="../Resources/NavigationDark.png" /> </phone:PhoneApplicationPage.Resources>
然后,在按钮中引用上述
ThemeBasedResourceConverter
:<Button> <Image Stretch="None" Source="{Binding Path=., RelativeSource={RelativeSource Self}, Converter={StaticResource ThemeBasedResourceConverter}}"> </Image> </Button>
以上就是 v1 的全部内容,各位!非常乐意收到您的任何反馈,并将不断开发 Synergy 工具包,让您在 WPF、WP7 或 Silverlight 中进行开发更加轻松!
历史
- 2011 年 1 月 30 日:初次发布