【发布时间】:2014-06-29 11:17:44
【问题描述】:
当我按下 UI 中的“保存设置”按钮时,我想保存 DataContext“值”,但我真的不知道该怎么做。我从 XML 文件中读取了一些设置,然后将它们绑定到不同的控件。阅读一些教程,我实现了“INotifyPropertyChanged”接口(我也不知道究竟是做什么的)到“GlobalSettings”类(这是我从我的 xml 文档中获取信息的地方)。
不知道自己解释的好不好,下面是代码……:
XAML 控件:
<GroupBox Grid.Row="0" Header="Multithreading related">
<CheckBox Content="Use Multithreading" IsEnabled="False" VerticalAlignment="Center" Margin="5,0,0,0"/>
</GroupBox>
<GroupBox Grid.Row="1" Header="Search level related">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<Label Content="Select the desired search level:" />
<ComboBox Width="200" Text="{Binding ProfileSelected}" x:Name="SearchLevelComboBox">
<ComboBoxItem>low</ComboBoxItem>
<ComboBoxItem>medium</ComboBoxItem>
<ComboBoxItem>high</ComboBoxItem>
</ComboBox>
</StackPanel>
</GroupBox>
<GroupBox Grid.Row="2" Header="Profiles related">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<CheckBox x:Name="UseProfilesCheckbox" IsChecked="{Binding UseProfiles}"
Grid.Row="0" Content="Use profiles system" VerticalAlignment="Center" Margin="5,0,0,0"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center">
<Label Content="Select the profile you want to edit:" />
<ComboBox x:Name="ProfilesComboBox"
Width="200">
<!-- Se llena dinamicamente -->
</ComboBox>
</StackPanel>
</Grid>
</GroupBox>
<GroupBox Grid.Row="3" Header="General settings">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" VerticalAlignment="Center" Orientation="Horizontal">
<Label Content="Select 'Bots' directory:" />
<TextBox Width="350" Margin="10,0,0,0" Text="{Binding DefaultPath}"/>
<Button Content="Select..." Margin="10,0,0,0" Padding="5" Width="75"/>
</StackPanel>
<StackPanel Grid.Row="1" VerticalAlignment="Center" Orientation="Horizontal">
<Label Content="Username:" />
<!-- Binding username to settings -->
<TextBox Width="150" Text="{Binding Username}" />
<Label Content="(*) Should be the same as your forum username" />
</StackPanel>
</Grid>
</GroupBox>
全局设置类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.IO;
using System.Xml;
using System.ComponentModel;
namespace SmartGUI.Settings
{
public class GlobalSettings : INotifyPropertyChanged
{
private bool _useMultithreading;
private string _searchLevel;
private bool _useProfiles;
private string _profileSelected;
private string _defaultPath;
private string _username;
public event PropertyChangedEventHandler PropertyChanged;
public bool UseMultithreading
{
get
{
return _useMultithreading;
}
set
{
_useMultithreading = value;
OnPropertyChanged("UseMultithreading");
}
}
public string SearchLevel
{
get
{
return _searchLevel;
}
set
{
_searchLevel = value;
OnPropertyChanged("SearchLevel");
}
}
public bool UseProfiles
{
get
{
return _useProfiles;
}
set
{
_useProfiles = value;
OnPropertyChanged("UseProfiles");
}
}
public string ProfileSelected
{
get
{
return _profileSelected;
}
set
{
_profileSelected = value;
OnPropertyChanged("ProfileSelected");
}
}
public string DefaultPath
{
get
{
return _defaultPath;
}
set
{
_defaultPath = value;
OnPropertyChanged("DefaultPath");
}
}
public string Username
{
get
{
return _username;
}
set
{
_username = value;
OnPropertyChanged("Username");
}
}
/// <summary>
///
/// </summary>
/// <param name="path">The path you will load the settings from (NOT IMPLEMENTED)</param>
/// <returns></returns>
public static GlobalSettings Load(string path = null)
{
var settings = new GlobalSettings();
try
{
if (!File.Exists("config.xml"))
{
// Changed the simple linq way to save xml documents to this horrible thing just because
// xml.linq doesn't allow to omit the enconding line in the document
var xmlConfig = new XElement("Settings");
xmlConfig.Add(new XElement("Multithreading", "false"));
xmlConfig.Add(new XElement("Searchlevel", "medium"));
xmlConfig.Add(new XElement("UseProfiles", "true"));
xmlConfig.Add(new XElement("CurrentProfile", "Defaut"));
xmlConfig.Add(new XElement("BotPath", ""));
xmlConfig.Add(new XElement("Username", "Unknown"));
var xmlSettings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true };
using (XmlWriter xmlOutFile = XmlWriter.Create("config.xml", xmlSettings))
{
xmlConfig.Save(xmlOutFile);
}
}
XElement root = XElement.Load("config.xml");
settings.UseMultithreading = Convert.ToBoolean(root.Element("Multithreading").Value);
settings.SearchLevel = root.Element("Searchlevel").Value;
settings.UseProfiles = Convert.ToBoolean(root.Element("UseProfiles").Value);
settings.ProfileSelected = root.Element("CurrentProfile").Value;
settings.DefaultPath = root.Element("BotPath").Value;
settings.Username = root.Element("Username").Value;
}
catch (Exception ex)
{
//Show error maybe
throw ex;
}
return settings;
}
public GlobalSettings()
{
}
public void Save()
{
try
{
var root = new XElement("Settings");
root.Add(new XElement("Multithreading", UseMultithreading));
root.Add(new XElement("Searchlevel", SearchLevel));
root.Add(new XElement("UseProfiles", UseProfiles));
root.Add(new XElement("CurrentProfile", ProfileSelected));
root.Add(new XElement("BotPath", DefaultPath));
root.Add(new XElement("Username", Username));
var xmlSettings = new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true };
using (XmlWriter xmlOutFile = XmlWriter.Create("config.xml", xmlSettings))
{
root.Save(xmlOutFile);
}
}
catch (Exception ex)
{
//Show error maybe
throw ex;
}
}
protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
}
然后在 MainWindow.xaml 我有:
private SmartGUI.Settings.GlobalSettings settings;
public MainWindow()
{
InitializeComponent();
settings = SmartGUI.Settings.GlobalSettings.Load();
DataContext = settings;
}
所有这些 cmet 都是因为我不是唯一一个使用解决方案的人,所以我评论所有内容以帮助我的伙伴理解。
如您所见,我可以在第一次加载窗口时设置控件的值,但现在我想将 datacontext 保存到 xml 设置文件中。
我认为用当前控件值替换 config.xml 可能是一个肮脏的解决方案,但肯定有更好的解决方案。
提前致谢。
【问题讨论】:
标签: wpf datacontext