我想保存DataContext"值"目前我按下"保存设置"用户界面中的按钮,但我真的不知道该怎么做。我从XML文件中读取了几个设置,然后将它们绑定到不同的控件。阅读一些教程我实现了" INotifyPropertyChanged"接口(我也不知道究竟是什么)对于" GlobalSettings" class(我从我的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>
GlobalSettings类:
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;
}
所有这些评论都是因为我不是唯一一个使用该解决方案的人,所以我评论所有内容以帮助我的伙伴们理解。
如您所见,我可以在第一次加载窗口时设置控件的值,但现在我想将datacontext保存到xml设置文件中。
我认为用当前控件值替换config.xml可能是一个肮脏的解决方案,但肯定有更好的解决方案。
提前致谢。
答案 0 :(得分:0)
嗯,首先,INotifyPropertyChanged
用于绑定。因此,如果将XAML上的属性绑定到ViewModel上的属性,然后该属性发生更改,它将触发一个事件,该事件最终会使View使用正确的值更新GUI。没有它,除非您重新加载代码,否则您将无法看到更改。
关于保存设置:
右键点击您的项目,然后选择Add -> new item -> Settings File.
现在,您可以在该文件中拥有所有类型的默认值。
您可以从文件中加载它们,将它们保存到文件中,并恢复默认值,因此它非常方便。
这里有一些代码可以向您展示如何使用它:
// Lets assume you want to save this
string something_to_save = "Remember for next run";
// Assuming you called your setting files: AppSetting.settings
// and that you have a string property called: some_property_you_defined
AppSettings.Default.some_property_you_defined = something_to_save;
// Run this to save the changes
AppSettings.Default.Save();
// Now, close the app, open the app, and then:
string this_is_awesome = AppSettings.Default.some_property_you_defined;
// it should have the value you saved.
答案 1 :(得分:0)
我已经完成了保存DataContext的工作。您只需从Button Click处理程序中调用save方法,如:
private void Save_OnClick(object sender, RoutedEventArgs e)
{
settings.Save();
}
如果您不想在代码隐藏文件中处理Click事件。您可以使用WPF命令在GlobalSettings类本身上调用Save方法。
您可以从以下位置获取我创建的代码... http://1drv.ms/1q5rqlx