C# WPF 将 RadioSelect bool 值保存到 XML 文件(它始终为 false)
C# WPF Saving RadioSelect bool value to XML File (it's always false)
这是收音机的XAML。没有其他人正在编辑这个。一旦设置,它就不会改变。但不知何故,无论将 XML 设置为“false”。
这是我保存 XML 文件的方法(效果很好)。
如您所见,有 3 个单选按钮,我试图将它们设置为 false 或 true,但它们都被保存为 false。
<RadioButton x:Name="sx80" Content="Cisco SX80" HorizontalAlignment="Left" Margin="701,244,0,0" VerticalAlignment="Top" GroupName="codecType" TabIndex="17" FontWeight="Normal" Height="25" Width="95" Padding="0,2"/>
class SaveXml
{
public static void savedata(object obj, string filename)
{
XmlSerializer sr = new XmlSerializer(obj.GetType());
TextWriter writer = new StreamWriter(filename);
sr.Serialize(writer, obj);
writer.Close();
}
}
这是主要的 class,告诉它我们要保存到 XML 文件的信息。
public class information
{
private string city;
private string chairCount;
private string stateSelect;
private string HostNameIPTyped;
private string VTCmac;
private string vtcUser;
private string vtcPass;
private string VTCserial;
private string AssetTag;
private string SIPURI;
private string SystemName;
private string firstName;
private string lastName;
private string contactPhone;
private string provisionerName;
private string provisionerInitials;
private string provisionDate;
private bool sx80;
private bool codecPlus;
private bool codecPro;
public string postcity
{
get { return city; }
set { city = value; }
}
public string postchairCount
{
get { return chairCount; }
set { chairCount = value; }
}
public string poststateSelect
{
get { return stateSelect; }
set { stateSelect = value; }
}
public string postHostNameIPTyped
{
get { return HostNameIPTyped; }
set { HostNameIPTyped = value; }
}
public string postVTCmac
{
get { return VTCmac; }
set { VTCmac = value; }
}
public string postvtcUser
{
get { return vtcUser; }
set { vtcUser = value; }
}
public string postvtcPass
{
get { return vtcPass; }
set { vtcPass = value; }
}
{ e164 = value; }
}
public string postVTCserial
{
get { return VTCserial; }
set { VTCserial = value; }
}
public string postAssetTag
{
get { return AssetTag; }
set { AssetTag = value; }
}
public string postSIPURI
{
get { return SIPURI; }
set { SIPURI = value; }
}
public string postSystemName
{
get { return SystemName; }
set { SystemName = value; }
}
public string postfirstName
{
get { return firstName; }
set { firstName = value; }
}
public string postlastName
{
get { return lastName; }
set { lastName = value; }
}
public string postcontactPhone
{
get { return contactPhone; }
set { contactPhone = value; }
}
public string postprovisionerName
{
get { return provisionerName; }
set { provisionerName = value; }
}
public string postprovisionerInitials
{
get { return provisionerInitials; }
set { provisionerInitials = value; }
}
public string postprovisionDate
{
get { return provisionDate; }
set { provisionDate = value; }
}
public bool postsx80
{
get { return sx80; }
set { sx80 = value; }
}
public bool postcodecPlus
{
get { return codecPlus; }
set { codecPlus = value; }
}
public bool postcodecPro
{
get { return codecPro; }
set { codecPro = value; }
}
}
您发布的代码未显示 RadioButton
上的任何数据绑定或您如何设置 DataContext
。但是您在评论中说字符串正在工作,所以我假设您已经在某处设置了 DataContext。如果您可以更新您的问题以显示您的 Window/View 是如何绑定到 information
对象的,那么将更容易为您提供更准确的解决方案。您还在您的评论之一中说了以下内容:
Yes, it is actually being saved as false. If it didn't find a value it would just show nothing. :-) <postsx80>false</postsx80>
bool
的默认值实际上是 false
,因此即使没有从 RadioButton 检索到任何值,您的 XML 文件仍将显示 false
。
您的 RadioButton 通常会像这样绑定,具体取决于您的 DataContext 是如何设置的。注意 IsChecked
属性 中的绑定。 Mode=TwoWay
表示 UI 可以设置 属性 的值而不仅仅是读取它:
<RadioButton x:Name="sx80" Content="Cisco SX80" IsChecked="{Binding Info.postsx80, Mode=TwoWay}" />
在这个 Window 背后的代码中,我创建了一个名为 Info
的 public 属性,其中包含一个 information
class.上面的 RadioButton 绑定了这个 information
实例的 postsx80
属性,所以你需要将这个实例传递给你的 savedata
方法,如下所示。
public partial class MainWindow : Window
{
public information Info { get; set; } = new information(); // The UI is bound to this instance
public MainWindow()
{
InitializeComponent();
this.DataContext = this; // I've set the Window's DataContext to itself
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SaveXml.savedata(Info, "somefile.xml");
}
}
您还应该实现 INotifyPropertyChanged
,它会在 属性 的值发生变化时通知 UI。例如,您的 information
class 可能如下所示:
// You will need to add the following namespaces
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace YourAppsNamespace
{
public class information : INotifyPropertyChanged // Implement the INotifyPropertyChanged interface
{
private bool sx80;
public bool postsx80
{
get { return sx80; }
set {
sx80 = value;
OnPropertyChanged(); // Notify the UI that this property's value has changed
}
}
// This code raises the event to notify the UI which property has changed
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
您需要将 OnPropertyChanged()
添加到所有属性的 setter 中。
您在评论中还提到您不知道如何使用自动属性。 auto 属性 基本上是编写 属性 的一种较短的方式,当在获取或设置值时不需要执行其他操作。例如,这个:
private bool someBool;
public bool SomeBool
{
get { return someBool; }
set { someBool = value; }
}
会变成:
public bool SomeBool { get; set; }
无需创建私有变量或定义 getter 和 setter 的主体。这是自动为您处理的。这仅适用于您不需要在 getter 或 setter 中执行任何其他操作的情况。因此,在我上面的示例中,我们需要在 setter 中调用 OnPropertyNotifyChanged()
,您将无法使用自动 属性.
另一个提示是,您只需在 Visual Studio 中键入 prop
,然后按 Tab 键两次即可插入自动 属性,而无需自己键入。然后您只需更改数据类型,再次按 Tab 键移动到名称并进行更改。可以对完整的 属性 执行相同的操作,就像您通过键入 propfull
.
编写的那样
这是收音机的XAML。没有其他人正在编辑这个。一旦设置,它就不会改变。但不知何故,无论将 XML 设置为“false”。
这是我保存 XML 文件的方法(效果很好)。 如您所见,有 3 个单选按钮,我试图将它们设置为 false 或 true,但它们都被保存为 false。
<RadioButton x:Name="sx80" Content="Cisco SX80" HorizontalAlignment="Left" Margin="701,244,0,0" VerticalAlignment="Top" GroupName="codecType" TabIndex="17" FontWeight="Normal" Height="25" Width="95" Padding="0,2"/>
class SaveXml
{
public static void savedata(object obj, string filename)
{
XmlSerializer sr = new XmlSerializer(obj.GetType());
TextWriter writer = new StreamWriter(filename);
sr.Serialize(writer, obj);
writer.Close();
}
}
这是主要的 class,告诉它我们要保存到 XML 文件的信息。
public class information
{
private string city;
private string chairCount;
private string stateSelect;
private string HostNameIPTyped;
private string VTCmac;
private string vtcUser;
private string vtcPass;
private string VTCserial;
private string AssetTag;
private string SIPURI;
private string SystemName;
private string firstName;
private string lastName;
private string contactPhone;
private string provisionerName;
private string provisionerInitials;
private string provisionDate;
private bool sx80;
private bool codecPlus;
private bool codecPro;
public string postcity
{
get { return city; }
set { city = value; }
}
public string postchairCount
{
get { return chairCount; }
set { chairCount = value; }
}
public string poststateSelect
{
get { return stateSelect; }
set { stateSelect = value; }
}
public string postHostNameIPTyped
{
get { return HostNameIPTyped; }
set { HostNameIPTyped = value; }
}
public string postVTCmac
{
get { return VTCmac; }
set { VTCmac = value; }
}
public string postvtcUser
{
get { return vtcUser; }
set { vtcUser = value; }
}
public string postvtcPass
{
get { return vtcPass; }
set { vtcPass = value; }
}
{ e164 = value; }
}
public string postVTCserial
{
get { return VTCserial; }
set { VTCserial = value; }
}
public string postAssetTag
{
get { return AssetTag; }
set { AssetTag = value; }
}
public string postSIPURI
{
get { return SIPURI; }
set { SIPURI = value; }
}
public string postSystemName
{
get { return SystemName; }
set { SystemName = value; }
}
public string postfirstName
{
get { return firstName; }
set { firstName = value; }
}
public string postlastName
{
get { return lastName; }
set { lastName = value; }
}
public string postcontactPhone
{
get { return contactPhone; }
set { contactPhone = value; }
}
public string postprovisionerName
{
get { return provisionerName; }
set { provisionerName = value; }
}
public string postprovisionerInitials
{
get { return provisionerInitials; }
set { provisionerInitials = value; }
}
public string postprovisionDate
{
get { return provisionDate; }
set { provisionDate = value; }
}
public bool postsx80
{
get { return sx80; }
set { sx80 = value; }
}
public bool postcodecPlus
{
get { return codecPlus; }
set { codecPlus = value; }
}
public bool postcodecPro
{
get { return codecPro; }
set { codecPro = value; }
}
}
您发布的代码未显示 RadioButton
上的任何数据绑定或您如何设置 DataContext
。但是您在评论中说字符串正在工作,所以我假设您已经在某处设置了 DataContext。如果您可以更新您的问题以显示您的 Window/View 是如何绑定到 information
对象的,那么将更容易为您提供更准确的解决方案。您还在您的评论之一中说了以下内容:
Yes, it is actually being saved as false. If it didn't find a value it would just show nothing. :-) <postsx80>false</postsx80>
bool
的默认值实际上是 false
,因此即使没有从 RadioButton 检索到任何值,您的 XML 文件仍将显示 false
。
您的 RadioButton 通常会像这样绑定,具体取决于您的 DataContext 是如何设置的。注意 IsChecked
属性 中的绑定。 Mode=TwoWay
表示 UI 可以设置 属性 的值而不仅仅是读取它:
<RadioButton x:Name="sx80" Content="Cisco SX80" IsChecked="{Binding Info.postsx80, Mode=TwoWay}" />
在这个 Window 背后的代码中,我创建了一个名为 Info
的 public 属性,其中包含一个 information
class.上面的 RadioButton 绑定了这个 information
实例的 postsx80
属性,所以你需要将这个实例传递给你的 savedata
方法,如下所示。
public partial class MainWindow : Window
{
public information Info { get; set; } = new information(); // The UI is bound to this instance
public MainWindow()
{
InitializeComponent();
this.DataContext = this; // I've set the Window's DataContext to itself
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SaveXml.savedata(Info, "somefile.xml");
}
}
您还应该实现 INotifyPropertyChanged
,它会在 属性 的值发生变化时通知 UI。例如,您的 information
class 可能如下所示:
// You will need to add the following namespaces
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace YourAppsNamespace
{
public class information : INotifyPropertyChanged // Implement the INotifyPropertyChanged interface
{
private bool sx80;
public bool postsx80
{
get { return sx80; }
set {
sx80 = value;
OnPropertyChanged(); // Notify the UI that this property's value has changed
}
}
// This code raises the event to notify the UI which property has changed
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}
您需要将 OnPropertyChanged()
添加到所有属性的 setter 中。
您在评论中还提到您不知道如何使用自动属性。 auto 属性 基本上是编写 属性 的一种较短的方式,当在获取或设置值时不需要执行其他操作。例如,这个:
private bool someBool;
public bool SomeBool
{
get { return someBool; }
set { someBool = value; }
}
会变成:
public bool SomeBool { get; set; }
无需创建私有变量或定义 getter 和 setter 的主体。这是自动为您处理的。这仅适用于您不需要在 getter 或 setter 中执行任何其他操作的情况。因此,在我上面的示例中,我们需要在 setter 中调用 OnPropertyNotifyChanged()
,您将无法使用自动 属性.
另一个提示是,您只需在 Visual Studio 中键入 prop
,然后按 Tab 键两次即可插入自动 属性,而无需自己键入。然后您只需更改数据类型,再次按 Tab 键移动到名称并进行更改。可以对完整的 属性 执行相同的操作,就像您通过键入 propfull
.