【发布时间】:2010-06-22 09:25:24
【问题描述】:
我是(非常)WPF 新手,对此我有疑问。这可能是一个非常愚蠢的问题,所以如果是这样,请原谅。
我正在做一个项目,我将我的文本框等绑定到单例类中的静态属性。我的问题是双向绑定不起作用。当文本框发生变化时,我可以看到属性的值发生变化,但是当属性发生变化时,我看不到文本框文本发生变化。
为了查看发生了什么,我编写了一个小应用程序,其中仅包含相关代码。请在下面找到代码。
在下面的代码中,我在不同的地方更改了文本框中的文本和源属性,并记录了我的观察结果。如果有人能告诉我我做错了什么并指出我正确的方向,我将不胜感激。
我也尝试过 INotifyPropertyChanged,但由于静态属性,它会出现问题。为静态属性实现 INotifyPropertyChanged 时是否有不同的方法。
提前致谢, 阿比。
XAML:
<Page x:Class="TestBindingApp.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Prefs="clr-namespace:TestBindingApp"
xmlns:cm="clr-namespace:System.ComponentModel;assembly=System"
xmlns:winForms="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
Title="Page1" Loaded="Page_Loaded">
<Page.Resources>
<Prefs:Class1 x:Key="TClass"></Prefs:Class1>
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Margin="15 5 5 0" Height="20">
<TextBlock Name="txbBankNumber" Margin="50 0 0 0" Padding="2">Bank Account Number :</TextBlock>
<TextBox Name="txtBankNumber" Margin="10 0 0 0" Width="100" MaxLength="8" HorizontalAlignment="Left">
<TextBox.Text>
<Binding Source="{StaticResource TClass}" Path="AccountNumber" Mode="TwoWay" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">
</Binding>
</TextBox.Text>
</TextBox>
</StackPanel>
</Grid>
XAML.CS:
namespace TestBindingApp
{
/// <summary>
/// Interaction logic for Page1.xaml
/// </summary>
public partial class Page1 : Page
{
public Page1()
{
InitializeComponent();
txtBankNumber.Text = "ABC";
// I can see the property AccountNumber changing here
Class1.AccountNumber = "123456";
// Value in txtBankNumber doesn't change here
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
txtBankNumber.Text = "ABCDE";
// I can see the property AccountNumber changing here
Class1.AccountNumber = "12345678";
// Value in txtBankNumber doesn't change here
}
}
}
Class Class1:
using System.ComponentModel;
namespace TestBindingApp
{
public class Class1
{
// Singleton instance
private static Class1 instance;
private static string _accountNumber;
public Class1()
{
}
// Singleton instance read-only property
public static Class1 Instance
{
get
{
if (instance == null)
{
instance = new Class1();
}
return instance;
}
}
public static string AccountNumber
{
get
{
return _accountNumber;
}
set
{
if (value != _accountNumber)
{
_accountNumber = value;
}
}
}
}
}
======================
无法在 cmets 中发布我更新的代码,因此更新我的原始帖子。
下面是我更新的代码,其中包含“if(PropertyChanged != null)”,但它给了我一个错误 - “非静态字段、方法或属性 'TestBindingApp.Class1 需要对象引用.NotifyPropertyChanged(字符串)'”。 .
我刚开始学习WPF,所以如果你能详细解释一下,那将非常有帮助。感谢您的耐心等待。
using System.ComponentModel;
namespace TestBindingApp
{
public class Class1: INotifyPropertyChanged
{
// Singleton instance
private static Class1 instance;
private static string _accountNumber;
public event PropertyChangedEventHandler PropertyChanged;
public Class1()
{
}
// Singleton instance read-only property
public static Class1 Instance
{
get
{
if (instance == null)
{
instance = new Class1();
}
return instance;
}
}
public static string AccountNumber
{
get
{
return _accountNumber;
}
set
{
if (value != _accountNumber)
{
_accountNumber = value;
NotifyPropertyChanged("AccountNumber");
}
}
}
private void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
==============
更新于英国时间 6 月 23 日上午 9:53
嗨,Arcturus,我已将属性更改为非静态的,但它的行为仍不符合我的预期。我是在期待它做一些它不应该做的事情,还是我做错了什么。 在下面的代码中,我希望文本框显示 12345678(或者可能是 123456)作为帐号,但它仍然显示 123。在调试模式下,我可以看到 PropertyChanged 事件在每个属性更改语句后正确执行,但值文本框不会改变。绑定仅在初始化时生效(InitializeComponent()),还是我在这里遗漏了什么?
页面代码隐藏
namespace TestBindingApp
{
/// <summary>
/// Interaction logic for Page1.xaml
/// </summary>
public partial class Page1 : Page
{
public Page1()
{
Class1.Instance.AccountNumber = "123";
InitializeComponent();
Class1.Instance.AccountNumber = "123456";
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
Class1.Instance.AccountNumber = "12345678";
}
}
}
Class1.cs
namespace TestBindingApp
{
public class Class1: INotifyPropertyChanged
{
// Singleton instance
private static Class1 instance;
private static string _accountNumber;
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public Class1()
{
}
// Singleton instance read-only property
public static Class1 Instance
{
get
{
if (instance == null)
{
instance = new Class1();
}
return instance;
}
}
public string AccountNumber
{
get
{
return _accountNumber;
}
set
{
if (value != _accountNumber)
{
_accountNumber = value;
OnPropertyChanged("AccountNumber");
}
}
}
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}
【问题讨论】: