在编程领域,将应用程序的设置保存在XML格式中已经成为一种标准做法。XML格式因其灵活性而广受欢迎,并且存在许多工具可以从XML架构生成类,使得使用.NET中的序列化类来保存或检索这些设置变得非常容易。
本文将介绍如何创建一个简单的应用程序,该应用程序包含一个自动生成的配置页面,这对于Windows Phone7开发者来说可能非常有用。
下面的图像展示了用于生成配置的XML架构。如所示,配置必须具有名称和数据类型,也可以包含XAML代码,如果不想自动生成控件;或者如果数据类型被定义为字符串数组,则必须提供字符串项列表。
简单应用程序由两个页面组成:MainPage和SettingsPage,一个包含XML架构的数据模型,转换为代码(XSD到类),以及一个示例配置文件(settings.xml)。该应用程序遵循Laurent Bugnion的Model-View-View-Model(MVVMLight)约定。
以下是应用程序使用的XML示例。
<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作为标签(标题),并根据需要分配数字或文本输入范围。一旦离开配置页面,设置就会被保存。
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 items = new List();
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模板以包含此页面并设置配置项。