简体   繁体   English

WPF中的双向绑定

[英]Two Way Binding in WPF

I am (very) new to WPF and I have got a question regarding that. 我是WPF的新手,对此我有一个疑问。 It may be a very stupid one, so please excuse me if that is the case. 这可能是非常愚蠢的,所以请原谅。

I am doing a project where I am binding my textboxes, etc to static properties inside a singleton class. 我正在做一个项目,将文本框等绑定到单例类中的静态属性。 My problem is that the twoWay Binding is not working. 我的问题是,双向绑定无法正常工作。 When the textbox changes, I can see that the value of the property changes, but when the property changes, I can't see the textbox text changing. 当文本框更改时,我可以看到属性的值更改了,但是当属性更改时,我看不到文本框的文本也更改了。

To see what's going on I wrote a small app, with just the relevant code. 为了了解发生了什么,我编写了一个带有相关代码的小应用程序。 Please find the code below. 请在下面找到代码。

In the code below, I am changing the text in the textbox and source property in various places and noted my observations. 在下面的代码中,我将在不同位置更改文本框和source属性中的文本,并注意我的观察。 If someone can tell me what I am doing wrong and point me in the right direction, I would be very grateful. 如果有人可以告诉我我做错了什么,并指出正确的方向,我将不胜感激。

I also tried INotifyPropertyChanged, but it gives problems because of the static property. 我也尝试过INotifyPropertyChanged,但是由于静态属性,它带来了问题。 Is there a different approach when implementing INotifyPropertyChanged for a static property. 为静态属性实现INotifyPropertyChanged时,是否有其他方法。

Thanks in advance, Abhi. 在此先感谢阿比。

XAML: 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: 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: 班级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;
            }
        }
    }
}

} }

===================== =====================

Couldn't post my updated code in the comments, so updating my original post. 无法在评论中发布我更新的代码,因此更新了我的原始帖子。

Below is my updated code, which has the "if(PropertyChanged != null)", but it gives me an error - "An object reference is required for the non-static field, method, or property 'TestBindingApp.Class1.NotifyPropertyChanged(string)'". 下面是我的更新代码,其中包含“ if(PropertyChanged!= null)”,但它给了我一个错误-“非静态字段,方法或属性'TestBindingApp.Class1.NotifyPropertyChanged(串)'”。 .

I have just started learning WPF, so if you could explain in detail, that would be very helpful. 我刚刚开始学习WPF,因此,如果您可以详细解释,那将非常有帮助。 Thanks for your patience. 谢谢你的耐心。

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));
    } 

}

} }

============== ==============

Updated 23rd June, 09:53 AM UK time 6月23日,英国时间上午9:53更新

Hi Arcturus, I have changed the properties to non-static, but it is still not behaving as I expect it to. 嗨,Arcturus,我已经将属性更改为非静态的,但是它仍然没有像我期望的那样运行。 Am I expecting it to do something which it isn't meant to do, or am I doing something wrong. 我是否期望它执行原本不打算做的事情,还是我做错了什么。 In the below code, I expected the textbox to show 12345678 (or maybe 123456) as the account number, but it still shows 123. In the debug mode, I can see PropertyChanged event executing correctly after each property change statement, but the value of the textbox doesn't change. 在下面的代码中,我希望文本框将帐号显示为12345678(或123456),但仍显示为123。在调试模式下,我可以看到PropertyChanged事件在每个属性更改语句之后都能正确执行,但是文本框不变。 Does the binding take affect only at the time of initialization (InitializeComponent()), or am I missing something here? 绑定仅在初始化(InitializeComponent())时才会生效,还是我在这里丢失了一些东西?

Page code-behind 页面代码隐藏

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 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));
        }
    } 

}
}

You really need the INotifyPropertyChanged interface: 您确实需要INotifyPropertyChanged接口:

using System.ComponentModel;

namespace TestBindingApp
{
public class Class1
{
    // Singleton instance
    private static Class1 instance;
    private string _accountNumber;
    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;
            NotifyPropertyChanged("AccountNumber");
        }
    }
    }

        public event PropertyChangedEventHandler PropertyChanged;


    private void NotifyPropertyChanged(string property)
    {
        if(PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
}

You call NotifyPropertyChanged from a static member, but NotifyPropertyChanged itself isn't static. 您从静态成员调用NotifyPropertyChanged,但NotifyPropertyChanged本身不是静态的。

Two ways to solve: Either make AccountNumber NOT static or provide an instance for your call to NotifyPropertyChanged (eg "Instance.NotifyPropertyChanged(...)") 有两种解决方法:使AccountNumber不是静态的或为您对NotifyPropertyChanged的调用提供实例(例如“ Instance.NotifyPropertyChanged(...)”)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM