自动生成设置页面





5.00/5 (3投票s)
自动生成 Windows Phone 7 设置页面。
引言
由于我们的大部分 Windows Phone 7 应用程序都需要一个配置页面,以便用户对应用程序本身进行任何调整,并且这项任务始终是一个重复性的任务,不需要任何额外的处理,所以我决定创建一个简单的应用程序,其中包含一个自动生成的配置页面,这对我们 Windows Phone 7 开发人员可能有所帮助。
背景
一段时间以来,在编程中,将应用程序的设置保存在 XML 格式中已成为标准。我决定使用 XML 格式,因为它非常通用,而且当然有一些实用程序可以从 XML 架构生成类,因此使用 .NET 中的序列化类来保存或检索这些设置非常容易。
代码解释
XML 架构
下图显示了用于生成配置的 XML 架构。如图所示,配置必须具有名称和数据类型,如果不想自行生成控件,还可以包含 XAML 代码;或者,如果数据类型定义为字符串数组,则必须提供字符串项目列表。
我使用 JDeveloper 创建此 XML 架构,因为我认为它是 XML 架构的最佳可视化编辑器之一,而且它是免费的。JDeveloper 有点慢,因此建议使用具有良好 CPU、足够内存的体面硬件,如果您有固态硬盘,那就更好了。
将数据类型分配给配置设置有助于自动生成配置控件:如果设置了 String
或 Numeric
数据类型,则会生成一个 TextBox
;如果是 Boolean
数据类型,它将生成一个 ToggleSwitch
,如果是 StringArray
数据类型,它将生成一个 ListPicker
控件。
MVVM 项目
我们简单的应用程序由两个页面组成:MainPage
和 SettingsPage
,一个包含 XML 架构的数据模型,转换为代码(XSD 到类),以及一个示例配置文件 (settings.xml)。反过来,此应用程序遵循 Model-View-View-Model 的约定 (MVVM Light) 由 Laurent Bugnion 提供。
该项目还引用了 Isolated Storage Explorer for WP7,这是因为应用程序可能需要对默认配置进行一些调整,以便我们可以从一个相当基本的配置开始,并最终确定一个配置文件 (settings.xml 经过调整和测试,一旦应用程序部署到 marketplace,它将成为默认配置文件)。
在我们的应用程序中,如果您愿意,我们使用了琐碎且毫无意义的设置,但它足以用于演示目的。
现在让我们详细看看代码。
<settings xmlns="http://www.inputstudiowp7.com/schemas">
<Setting Name="Use Location" Type="Boolean" Value="True"/>
<Setting Name="Providers" Type="StringArray" Value="Item 2">
<StringItem Value="Item 1"/>
<StringItem Value="Item 2"/>
<StringItem Value="Item 3"/>
</Setting>
<Setting Name="Nick Name" Type="String" Value="Undefined"/>
<Setting Name="Age" Type="Integer" Value="18"/>
</settings>
主页只有我们主 Model-View 的几个属性和一个指向设置页面的超链接。设置页面是一个空的 Grid
,页面加载后会自行生成控件。
主页
|
设置页面
|
![]() |
![]() |
至于设置页面中自行生成的控件,当页面加载发生时,代码会迭代每个设置,并根据其类型生成输入控件,并分配一个 TextBlock
作为标签(Caption)和一个数字或文本输入范围(如果适用)。离开配置页面后,将保存设置。
public partial class SettingsPage : PhoneApplicationPage
{
public MainViewModel model { get { return this.DataContext as MainViewModel; } }
public SettingsPage()
{
InitializeComponent();
this.Loaded += new System.Windows.RoutedEventHandler(Settings_Loaded);
}
void Settings_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
Grid grid = this.FindName("LayoutRoot") as Grid;
if (null != grid)
{
StackPanel spContent = new StackPanel();
foreach (Setting setting in model.Settings.Setting)
{
TextBlock tbCaption =
new TextBlock() { Text = string.Format("{0}",
setting.Name.Trim()), Margin = new Thickness(12, 0, 0, 0) };
switch (setting.Type)
{
case eDataType.Boolean:
ToggleSwitch tsOption = new ToggleSwitch()
{
Name = string.Format("ts{0}",
setting.Name.Replace(" ", string.Empty)),
Header = setting.Name
};
tsOption.SetBinding(ToggleSwitch.IsCheckedProperty,
new Binding("Value")
{ Mode = BindingMode.TwoWay, Source = setting });
spContent.Children.Add(tsOption);
break;
case eDataType.String:
case eDataType.Integer:
case eDataType.Decimal:
TextBox txtValue = new TextBox()
{
Name = string.Format("txt{0}",
setting.Name.Replace(" ", string.Empty)),
Height = 72,
MaxLength = 50,
TextWrapping = TextWrapping.NoWrap
};
txtValue.SetBinding(TextBox.TextProperty,
new Binding("Value") { Mode = BindingMode.TwoWay,
Source = setting });
txtValue.InputScope = new InputScope()
{
Names = { new InputScopeName() {
NameValue = (setting.Type.Equals(eDataType.String)
? InputScopeNameValue.Text
: InputScopeNameValue.Number) } }
};
spContent.Children.Add(tbCaption);
spContent.Children.Add(txtValue);
break;
case eDataType.StringArray:
ListPicker lpValue = new ListPicker()
{
Header = string.Format("{0}", setting.Name.Trim())
};
List<string> items = new List<string>();
foreach (StringItem item in setting.StringItem)
items.Add(item.Value);
lpValue.ItemsSource = items;
lpValue.SetBinding(ListPicker.SelectedItemProperty,
new Binding("Value")
{ Mode = BindingMode.TwoWay, Source = setting });
spContent.Children.Add(lpValue);
break;
}
}
grid.Children.Add(spContent);
}
}
protected override void OnNavigatedFrom(
System.Windows.Navigation.NavigationEventArgs e)
{
model.saveSettings();
base.OnNavigatedFrom(e);
}
}
另外,当发生灾难性故障时,应用程序会发送电子邮件。
关注点
如果您发现此自动生成的设置页面很有用,则可以修改 Visual Studio 模板以包含此页面并设置配置项目。
这只是构建完全可配置设置页面的起点。
历史
此帖子的第一个版本。 这是我在 CodeProject 中的第二个帖子。